September 27th, 2011

Create a Custom Object from WMI by Using PowerShell

Doctor Scripto
Scripter

Summary: Create a custom object from WMI to display processor and operating system information using Windows PowerShell.

 

Hey, Scripting Guy! QuestionHey, 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

 

Hey, Scripting Guy! AnswerHello 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.

Image of command and associated output

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.

Image of credential dialog box

I added an array of properties to store the operating system information:

$osProperty = “Caption”, “OSArchitecture”,”ServicePackMajorVersion”

This change is shown in the following figure.

Image of the change

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.

Image of this portion of revised code

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.

Image of this portion of new code

When the script runs, the following output is displayed.

Image of output displayed when script is run

 

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

 

 

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.