Categories Articles

WMI or CIM in your PowerShell scripts: Which should you use?

A few months ago, I presented a PowerShell-related session at a tech conference. Following my presentation, someone asked me if they should be basing their PowerShell scripts around the use of WMI or if it is better to use CIM.

For those who might not be familiar with these terms, WMI stands for Windows Management Instrumentation. Microsoft exposes WMI in PowerShell through Get-WmiObject and other related cmdlets. These cmdlets make it possible to access parts of the operating system that would be difficult or impossible to get to using native, non-WMI-related PowerShell cmdlets.

In contrast, CIM is the Common Information Model. You can use it to do a lot of the same things as you can accomplish using WMI. However, CIM is a lot newer than WMI, at least as far as PowerShell is concerned. Microsoft first introduced CIM support in Windows Server 2012 and Windows 8.

So, going back to my original question, should you be using WMI in your PowerShell scripts, or is it better to use CIM?

WMI or CIM? It depends

The answer to this question probably depends on who you ask. If you were to ask someone at Microsoft whether you should be using WMI or CIM, I’m betting that they would almost certainly tell you to use CIM whenever possible. I will talk about some of the reasons for that in a moment.

My answer to this question is a little bit different from the answer that I think that Microsoft would probably give you. My answer would be that you should use whatever works best for you. While there are undoubtedly advantages to using CIM, WMI is still fully supported. If you feel more comfortable using WMI — and WMI will allow you to do whatever it is that you are trying to do — then there is nothing wrong with using it. I often catch myself using WMI in my scripts, simply because I got into the habit of using it before PowerShell started supporting CIM.

A far more important consideration, however, is that there may be situations in which you have no choice but to use WMI. For example, CIM may not expose a particular attribute that you need access to. I will show you an example of that later on.

Having said that, there are certain advantages to using CIM in your scripts. By far the biggest advantage of using CIM instead of WMI is that CIM is designed to work in heterogeneous environments. WMI works really well for managing Windows machines, but it isn’t an option for managing other platforms.

Before CIM, PowerShell management of non-Windows machines was often done through the WSMan protocol, which was implemented through WinRM. Although WinRM cmdlets could be used for multiplatform management, doing so wasn’t always easy.

The CIM model is specifically intended to overcome these limitations. Most (but not all) of the CIM-related cmdlets use a syntax that is very similar to that of the WMI cmdlets. Unlike WMI though, CIM adheres to the DMTF standard, which makes it ideal for use in heterogeneous environments.

Available CIM cmdlets

As previously mentioned, most of the CIM-related cmdlets are designed to work in a manner that is very similar to their WMI counterparts. Many of the cmdlets are so similar that you can simply replace the letters WMI with CIM and leave everything else the same. For example, the CIM equivalent to the Set-WmiInstance cmdlet is Set-CimInstance. Not all of the cmdlets match up exactly, but you will find that more often than not a WMI cmdlet can simply be replaced by its CIM equivalent.

Here is a list of WMI cmdlets and their corresponding CIM cmdlets, as specified by Microsoft:

  • Get-WmiObject Get-CimInstance
  • Get-WmiObject -list Get-CimClass
  • Set-WmiInstance Set-CimInstance
  • Set-WmiInstance –PutType CreateOnly New-CimInstance
  • Remove-WmiObject Remove-CimInstance
  • Invoke-WmiMethod Invoke-CimMethod

A few examples

So now that I have talked a bit about some of the similarities and differences between WMI and CIM, I want to show you a couple of examples of WMI cmdlets being used alongside their CIM cmdlets.

The first example that I want to show you is shown in the figure below. Here, I have used the Get-WmiObject cmdlet (left) and the Get-CimInstance cmdlet (right) to retrieve CPU information.


At first glance, these two screen captures look quite a bit different from one another. The biggest difference, however, is in the way that the information is being presented. Get-WmiObject is formatting its output as a list, while Get-CimInstance is displaying its output in table form. The actual information that is being displayed is mostly the same.

This isn’t to say that there are no differences between the two cmdlets. The Get-WmiObject cmdlet supports some attributes that the Get-CimInstance cmdlet does not. To show you what I mean, I have created another comparative screen capture with the Get-WmiObject cmdlet being used on the left, and the Get-CimInstance cmdlet being used on the right.

To make these screen captures easier to read, I included the instruction Where-Object {$_.DeviceID -eq ‘CPU0’}. Since this server has multiple CPUs, I used this instruction as a filter so that PowerShell would only display each attribute once, as opposed to displaying the attributes once for each CPU.

The other thing that I did was to use the Select-Object * cmdlet and FL (Format-List) to force PowerShell to display a list of all of the available attributes. If you look at the figure below, you can see that several attributes can be displayed through WMI, but not CIM.


So, is it WMI or CIM?

As you can see, Microsoft has made it relatively easy for those who are used to using WMI cmdlets to make the transition to CIM. Even so, I am a big believer in using whatever techniques and cmdlets work best for your own unique situation. In most cases, it probably is better to use CIM than WMI. One big exception, however, is that if you need to manage systems that are older than Windows Server 2012, you will be better off sticking to using WMI. Likewise, if you need to reference an attribute that isn’t supported by CIM, then you will have to resort to using WMI.

Brien Posey

Brien Posey is a freelance technology author and speaker with over two decades of IT experience. Prior to going freelance, Brien was a CIO for a national chain of hospitals and healthcare facilities. He has also served as a network engineer for the United States Department of Defense at Fort Knox. In addition, Brien has worked as a network administrator for some of the largest insurance companies in America. To date, Brien has received Microsoft’s MVP award numerous times in categories including Windows Server, IIS, Exchange Server, and File Systems / Storage. You can visit Brien’s Website at: www.brienposey.com.

Share
Published by
Brien Posey

Recent Posts

Need to recover failed member of a database availability group? Read this guide

Sponsored by Stellar Data RecoveryIf you ever need to recover a failed member of an…

2 hours ago

Implementing end-to-end API security in the Microsoft stack

The Microsoft stack is becoming increasingly important for development within enterprise environments. That’s why investing…

19 hours ago

Delete Microsoft Teams cache fast with this PowerShell one-liner

Microsoft Teams cache is stored in numerous places, so to delete it is time-consuming. This…

23 hours ago

Bias against women in the tech industry: It doesn’t have to be this way

Most people have biases—conscious or unconscious. In the tech industry, this bias disproportionately affects women.…

1 day ago

RAID 10 vs. RAID 5: When to use each level and why

RAID levels are disk configurations that provide certain benefits. In this article, we’ll compare RAID…

2 days ago

Simplifying cloud complexity: 4 roads to the same destination

As cloud computing grows, the sheer number of options can be a problem. But there…

2 days ago