Summary: Create a custom object from WMI to display processor and operating system information using Windows PowerShell.
Hey, Scripting Guy! Your script yesterday was pretty cool. However, in addition to obtaining information about the processor, I also need to know operating system is 32-bit or 64-bit, the version of Windows that is installed, and the service pack that is installed. I hate to be picky, but this is the information I need in order to plan for our upgrade project.
—BB
Hello BB,
Microsoft Scripting Guy Ed Wilson here. First, I need to apologize to the Scripting Wife. Yesterday was her birthday, and I did not mention it in the Hey, Scripting Guy! Blog. Sorry!
Beyond the disappointed Scripting Wife, BB, I am glad you enjoyed yesterday’s article. It is one of those things that sort of gets out of control. I begin working on a script and keep adding to it. So I will simply continue adding to it for today.
First, make sure you have the script from yesterday’s Hey Scripting Guy! Article. The script, as it stood at the end of yesterday, is shown here:
Import-Module ActiveDirectory
$pingConfig = @{
"count" = 1
"bufferSize" = 15
"delay" = 1
"EA" = 0 }
$computer = $cn = $null
$cred = Get-Credential
Get-ADComputer -filter * -Credential $cred |
ForEach-Object {
if(Test-Connection -ComputerName $_.dnshostname @pingconfig)
{ $computer += $_.dnshostname + "`r`n"} }
$computer = $computer -split "`r`n"
$property = "systemname","maxclockspeed","addressWidth",
"numberOfCores", "NumberOfLogicalProcessors"
foreach($cn in $computer)
{
if($cn -match $env:COMPUTERNAME)
{
Get-WmiObject -class win32_processor -Property $property |
Select-Object -Property $property }
elseif($cn.Length -gt 0)
{
Get-WmiObject -class win32_processor -Property $property -cn $cn -cred $cred |
Select-Object -Property $property } }
Now, let’s see if I can find the additional information you need for your upgrade project. Actually, it is pretty simple because everything you need is in the Win32_OperatingSystem WMI class. The Win32_OperatingSystem WMI class is documented on MSDN, but the properties needed for today’s script are rather straightforward and do not need extensive documentation. A quick check of the Win32_Operatingsystem WMI class reveals everything I need. The command I use to perform this check is shown here (gwmi is an alias for Get-WmiObject and fl is alias for Format-List):
gwmi win32_operatingsystem | fl *
The command and associated output are shown in the following figure.
The revised script is named GetADComputersAndWMiProcessorAndOSInfo.ps1.
GetADComputersAndWMiProcessorAndOSInfo
Import-Module ActiveDirectory
$pingConfig = @{
"count" = 1
"bufferSize" = 15
"delay" = 1
"EA" = 0 }
$computer = $cn = $null
$cred = Get-Credential
Get-ADComputer -filter * -Credential $cred |
ForEach-Object {
if(Test-Connection -ComputerName $_.dnshostname @pingconfig)
{ $computer += $_.dnshostname + "`r`n"} }
$computer = $computer -split "`r`n"
$property = "systemname","maxclockspeed","addressWidth",
"numberOfCores", "NumberOfLogicalProcessors"
$osProperty = "Caption", "OSArchitecture","ServicePackMajorVersion"
foreach($cn in $computer)
{
if($cn -match $env:COMPUTERNAME)
{
$obj = Get-WmiObject -class win32_processor -Property $property |
Select-Object -Property $property
$os = Get-WmiObject -class win32_OperatingSystem -Property $osproperty |
Select-Object -Property $osproperty
} #end if
elseif($cn.Length -gt 0)
{
$obj = Get-WmiObject -class win32_processor -Property $property -cn $cn -cred $cred |
Select-Object -Property $property
$os = Get-WmiObject -class win32_OperatingSystem -Property $osproperty -cn $cn -cred $cred |
Select-Object -Property $osproperty
} #end elseif
New-Object psobject -Property @{
"name" = $obj.systemname
"speed" = $obj.maxclockspeed
"addressWidth" = $obj.addressWidth
"numberCores" = $obj.numberOfCores
"numberLogicalProcessors" = $obj.NumberOfLogicalProcessors
"OSname" = $os.Caption
"OSArchitecture" = $os.OSArchitecture
"ServicePack" = $os.ServicePackMajorVersion
}
#$os
} #END FOREACH
When the script runs, the first thing that happens is a credential dialog box displays. This is because I request credentials for connection to remote systems. The credentials are not used to connect to the local computer. The credential dialog box is shown in the following figure.
I added an array of properties to store the operating system information:
$osProperty = "Caption", "OSArchitecture","ServicePackMajorVersion"
This change is shown in the following figure.
In addition, I changed the portion of the script inside the Foreach loop so that I am storing the Processor object instead of directly emitting. I also added a WMI query to retrieve the operating system information. The revised section is shown here:
foreach($cn in $computer)
{
if($cn -match $env:COMPUTERNAME)
{
$obj = Get-WmiObject -class win32_processor -Property $property |
Select-Object -Property $property
$os = Get-WmiObject -class win32_OperatingSystem -Property $osproperty |
Select-Object -Property $osproperty
} #end if
elseif($cn.Length -gt 0)
{
$obj = Get-WmiObject -class win32_processor -Property $property -cn $cn -cred $cred |
Select-Object -Property $property
$os = Get-WmiObject -class win32_OperatingSystem -Property $osproperty -cn $cn -cred $cred |
Select-Object -Property $osproperty
} #end elseif
This portion of the revised code is shown in the following figure.
To make it easier to work with the output, I decided to return a custom object. This object contains information from both WMI classes. In addition, I changed some of the column headings to make it easier to read. This section of the script that creates the new object is shown here:
New-Object psobject -Property @{
"name" = $obj.systemname
"speed" = $obj.maxclockspeed
"addressWidth" = $obj.addressWidth
"numberCores" = $obj.numberOfCores
"numberLogicalProcessors" = $obj.NumberOfLogicalProcessors
"OSname" = $os.Caption
"OSArchitecture" = $os.OSArchitecture
"ServicePack" = $os.ServicePackMajorVersion
} #end new object
This portion of the new code is shown in the following figure.
When the script runs, the following output is displayed.
BB, that is all there is to using Windows PowerShell to query for both processor and operating system information.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy