Denys Rudyi - Fotolia
How to use WMI and the CIM standard with Windows PowerShell
WMI, Microsoft's implementation of the CIM standard, lets admins use PowerShell commands to view and modify system data and configuration.
Since the first PowerShell release, Microsoft has included support for WMI, the de facto Windows management system since the days of Windows NT. Back then, PowerShell included several cmdlets that let you access WMI data on both local and remote computers. After the initial PowerShell release, Microsoft added to and improved on the WMI features within PowerShell, but the basic functionality remained the same.
When Microsoft released PowerShell 3, the company introduced a new set of cmdlets that were designed to take advantage of the Common Information Model (CIM) standard, which had served as the foundation for Windows Management Instrumentation since its inception. The new cmdlets made remote Windows management easier and more efficient, and they continued to do so with the release of PowerShell 4 and 5. This made PowerShell a more robust tool than ever for performing Windows management tasks.
The CIM and WMI landscape
The CIM and WMI story begins with the Distributed Management Task Force (DMTF), which works to define industry standards and drive their adoption to help simplify the management of network-accessible technologies. One such standard is the Common Information Model, which describes the structure and behavior of managed resources, such as computer hardware and software components.
Every Windows server and client computer has a local CIM repository that contains a wide range of management information. The repository is similar to a database in that you can retrieve information, set property values and perform other tasks against the data. The latest version of the CIM standard was released in May 2016.
WMI is Microsoft's implementation of the CIM standard. WMI delivers management capabilities to the Windows platform. It exposes hardware and software data via a standard interface, which provides a consistent way to view and, in some cases, modify system data and configuration settings. Through WMI, you can gather a wide range of information about components such as disks, registry keys, running processes, installed services, IP addresses and much more.
The CIM and WMI information is organized hierarchically; the namespace is at the highest level. The default namespace -- and the one you're likely to encounter the most -- is Root\CIMV2. The Root\CIMV2 namespace defines a group of related classes that represent various types of managed components supported by the CIM standard.
Windows components are represented as WMI objects (class instances) that expose properties about each component. For example, the Root\CIMV2 namespace includes the Win32_Service class, which represents a service on a Windows system. If you query the CIM repository for a list of services installed on a Windows computer, WMI will return each service as a Win32_Service object.
WMI facilitates the maintenance and access of the CIM data through the use of providers and the WMI Query Language (WQL). Providers are COM-based DLLs that work in the background to gather the various types of management data into the repository. WQL is a SQL-like language you can use to return data from the repository back to a client tool, such as PowerShell.
WMI in PowerShell
Since its inception, PowerShell has had the capacity to interface with WMI, which makes it possible to use the PowerShell scripting language in conjunction with WMI data. PowerShell currently supports the WMI cmdlets described in the following table:
The Get-WmiObject cmdlet is one of the oldest and most commonly used WMI-related cmdlets in PowerShell. Like any cmdlet, you can use it alone or with other language elements. For example, the following PowerShell command uses Get-WmiObject to retrieve the object associated with the SQLBrowser service and then pipes that object to the Invoke-WmiMethod cmdlet to call the StopService method:
Get-WmiObject Win32_Service -Filter "Name = 'SQLBrowser'" | Invoke-WmiMethod -Name StopService
The Get-WmiObject command specifies the Win32_Service class and then uses an expression ("Name = 'SQLBrowser'") to call the specific service. The cmdlet returns a Win32_Service object for the SQLBrowser service, which is sent down the pipeline to the Invoke-WmiMethod cmdlet. Because the object is already in the pipeline, you must only specify the method you want to execute, in this case, StopService.
In theory, you can also run this command against a remote computer, assuming you don't run into any glitches when trying to do so. When Microsoft implemented WMI, the CIM standard had yet to define a communication protocol, so Microsoft came up with its own, the Distributed Component Object Model (DCOM), which was based on the Remote Procedure Call protocol. Unfortunately, firewalls and networking equipment often presented challenges for DCOM, adding to the complexity of remote WMI administration.
CIM in PowerShell
With the release of PowerShell 3, Microsoft introduced a new line of cmdlets that addressed the DCOM limitations and improved on CIM integration. The following table describes each of the new cmdlets:
Many of the new CIM cmdlets work the same way as their WMI counterparts. For example, you can use the Get-CimInstance cmdlet similar to how you use Get-WmiObject, and you can use the Invoke-CimMethod cmdlet similar to how you use the Invoke-WmiMethod, as shown in the following PowerShell command:
Get-CimInstance Win32_Service -Filter "Name = 'SQLBrowser'" | Invoke-CimMethod -Name StopService
The command returns the same results as the previous example, except that it uses the new cmdlet names.
Not all cmdlets work the same way as their WMI counterparts. For example, you can use the Set-WmiInstance cmdlet to create or modify WMI objects, but the CIM cmdlets separate these operations. The New-CimInstance cmdlet creates an instance, and the Set-CimInstance cmdlet modifies an instance.
The CIM cmdlets also include features not available to the WMI cmdlets. A good example of this is the Get-CimAssociatedInstance cmdlet, which lets you view the instances associated with a specified instance, something you cannot easily do with the WMI cmdlets.
When developing the CIM cmdlets, Microsoft tried to preserve the WMI cmdlet functionality where it made sense -- which eases the transition to the CIM cmdlets -- but updated and augmented the new cmdlets as necessary to better interface with the CIM data.
Perhaps the biggest area where the CIM cmdlets diverge from the WMI cmdlets is in their remoting protocols. By default, the CIM cmdlets use Windows Remote Management (WinRM), rather than DCOM. WinRM is Microsoft's implementation of WS-Management, a Simple Object Access Protocol-based remoting protocol that is far more firewall and network-friendly than DCOM.
By using WinRM, the CIM cmdlets can much more easily connect to remote computers, not only Windows computers, but any CIM-enabled system. In addition, you can still revert to DCOM to connect to systems running older versions of Windows and PowerShell.
Upgrade to PowerShell 5
Using WMI with PowerShell scripts