WMI CIM-plified Part 2: PowerShell 3.0
The second part of Jeffery's series will show the relationship between CIM and PowerShell.
- By Jeffery Hicks
PowerShell 3.0 brings us into the world of CIM which I think you'll find to be a much easier approach for systems management using WMI. On the surface the syntax hasn't really changed much. We have a cmdlet to get instances of a WMI class either by class name or a filter. This is what we used to do:
PS C:\scripts> get-wmiobject win32_operatingsystem
SystemDirectory : C:\Windows\system32
BuildNumber : 9200
RegisteredUser : Windows User
SerialNumber : 00178-10070-21231-AA839
Version : 6.2.9200
The command doesn't change much other than the cmdlet name.
PS C:\scripts> get-ciminstance win32_operatingsystem
SystemDirectory Organization BuildNumber RegisteredUser SerialNumber Version
--------------- ------------ ----------- -------------- ------------ -------
C:\Windows\sy... 9200 Windows User 00178-10070-..6.2.9200
Yes, there are some cosmetic changes but there are also some substantive changes as well. Let's look at the object we get back.
PS C:\scripts> $a = get-wmiobject win32_operatingsystem
PS C:\scripts> $b = get-ciminstance win32_operatingsystem
PS C:\scripts> $a.gettype().name
PS C:\scripts> $b.gettype().name
For the most part you probably won't care. But these are two different types of objects with some noticeable differences. First, date time formats are now rendered in a friendly date-time format. The WMI object requires some work to reformat the property.
PS C:\scripts> $a.LastBootUpTime
PS C:\scripts> $a.ConvertToDateTime($a.lastbootuptime)
Monday, March 25, 2013 2:05:01 PM
But the CIM object formats the property automatically.
PS C:\scripts> $b.LastBootUpTime
Monday, March 25, 2013 2:05:01 PM
Another thing you'll notice is that if you pipe the objects to Select * or Format-List * you won't see any system properties.
PS C:\scripts> $a.__Path
PS C:\scripts> $b.__Path
Most of the time we don't need these properties anyway.
The last major difference is that the CIM object doesn't return any WMI methods. If you pipe the CIM object to Get-Member you'll see a few methods, but those are added by PowerShell and are not part of the WMI object. It is still possible to invoke WMI methods on an object using the CIM cmdlets, and we'll look at that in a future lesson. But for now, while I could do this:
PS C:\scripts> $a.Shutdown()
It won't work with the CIM-based object.
PS C:\scripts> $b.Shutdown()
You can retrieve WMI objects with Get-CIMInstance just as you would with Get-WMIObject. All of these commands are very similar to what you have probably used in the past.
PS C:\scripts> get-ciminstance win32_logicaldisk -filter "drivetype=3"
PS C:\scripts> get-ciminstance -query "Select DeviceID,Size,FreeSpace from Win32_logicaldisk where drivetype=3"
PS C:\scripts> get-ciminstance -namespace root/SecurityCenter2 -class AntiSpywareProduct
What is really handy is that there is tab completion for namespaces and classes so for the last command I only had to type part of the namespace and class and tab completed the command.
The underlying WMI data has not changed with PowerShell 3.0. What changed is the way that we access it. You can continue with the WMI cmdlets in PowerShell, but I encourage you to start looking at the newer CIM cmdlets. Even if your servers are not running PowerShell, you should be able to retrieve WMI information. Next time we'll look a bit more at the networking magic that makes this all happen.
More on this topic:
Jeffery Hicks is a multi-year Microsoft MVP in Windows PowerShell, Microsoft Certified Professional and an IT veteran with almost 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He works today as an independent author, trainer and consultant.