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:

Published by
Brien Posey

Recent Posts

PowerShell parameters: Controlling the input of your scripts

PowerShell has options to control the input and save code from being validated during execution. This tutorial looks at the…

13 hours ago

AWS unveils Graviton2, a blazing-fast processor to power its cloud

At its re:Invent conference in Las Vegas, AWS had some big news on a new datacenter processor. The Graviton2 has…

18 hours ago

Restoring Microsoft Teams data: A step-by-step guide

Restoring Microsoft Teams data is not simple, given the number of places data is stored. Luckily, the addition of private…

21 hours ago

Raccoon Stealer malware newest business email compromise attack

A simple yet versatile malware called Raccoon Stealer that bypasses anti-spam filters looks like it is going to be a…

2 days ago

Use PowerShell to determine the IP address your VMs are using

Can an admin gain access to a VM’s network configuration details such as the IP address without logging in to…

2 days ago

Datacenter migration using Veeam Backup & Replication: A walkthru

Moving a datacenter doesn't sound easy, but if you use the right tools and follow good procedures, even datacenter migration…

2 days ago