Introduction to CIM Cmdlets

PowerShell 3.0 shipping with Windows server 2012 and Windows 8 brings a new set of Cmdlets to manage any server or device that complies with CIM and WS-Man standards defined by DMTF. In this blog post we will explore these new Cmdlets and how can they help IT Pros in managing a datacenter.

The list of new Cmdlets is given in the table below:

Cmdlet

Purpose

Get-CimInstance

Gets instances of a class.

New-CimInstance

Creates a new instance of a class.

Remove-CimInstance

Removes one of more instances of a class.

Set-CimInstance

Modifies one or more instances of a class.

Get-CimAssociatedInstance

Gets all the associated instances for a particular instance.

Invoke-CimMethod

Invokes instance or static method of a class.

Get-CimClass

Gets class schema of a CIM class.

Register-CimIndicationEvent

Helps subscribe to events.

New-CimSession

Creates a CIM Session with local or a remote machine

Get-CimSession

Gets a list of CIM Sessions that have been made.

Remove-CimSession

Removes CimSessions that are there on a machine.

New-CimSessionOption

Creates a set of options that can be used while creating a CIM session.

Basic terminology

If you are already familiar with terms like WMI, CIM, WinRM and WS-Man, you can skip this section.

CIM: Common Information Model (CIM) is the DMTF standard [DSP0004] for describing the structure and behavior of managed resources such as storage, network, or software components.

WMI: Windows Management Instrumentation (WMI) is a CIM server that implements the CIM standard on Windows.

WinRM: Windows Remote Management (WinRM) is the Microsoft implementation of the WS-Man protocol on Windows.

Why new Cmdlets

With Windows Server 2012, Windows has shifted its focus to become a Cloud OS. In a datacenter running a private or public cloud – there are always set of devices and servers from different vendors. We strongly believe that the only way to reduce the cost of running datacenters is through automation built on top of standards. There is less learning and less chances of error when IT Pros are able to automate heterogeneous environment using same set of tools that they have learned for Windows.

This was not the case with previous versions of PowerShell. We had two set of Cmdlets to manage Windows and Non-Windows. WMI Cmdlets were primarily used to manage Windows and WsMan Cmdlets were targeted at non-Windows that implemented WsMan standard.

We heard from you that the major obstacle in PS scripting for WMI is lack of discoverability. We also heard that WMI Cmdlets don’t provide first class PS experience. There are issues with serializing a WMI object, there is no concept of session reuse and WMI object has weird looking property names (like __Server). Last but not least, there is poor formatting for most of the commonly used WMI classes. Someone said “When I run Get-WmiObject Win32_process, I feel like standing on bridge above freeway and lot of traffic zipping in front of my eyes”.

Key goals for new CIM Cmdlets

- Rich PowerShell experience. Make CIM a first class citizen of PS, addressing usability concerns and user feedback for WMI and WsMan Cmdlets.

- Standard compliance. With so much focus on standards, our goal is to make PowerShell the best platform for managing Windows and Non-Windows. New CIM Cmdlets should be able to manage any CIM + WsMan compliant endpoint, including Windows.

- Support for down-level machines. We understand that there are more down-level servers in a datacenter than there would be Windows Server 2012 for some time to come. We want to make sure same set of Cmdlets can be used to manage down-level Windows as well.

In the subsequent sections we will talk about each of these goals in detail.

Goal 1 - Rich PowerShell experience

1. Discovery of classes and namespaces.

There is a famous joke about WMI, often attributed to Jeffrey Snover. “IT Pros love and hate WMI. They love it because there is so much they accomplish with WMI and PowerShell. They hate it because it is very difficult to discover what’s in there”

Get-CimClass and tab completion described above only works for local machine. If you specify ComputerName or CimSession parameter, tab completion would not work. In order to make tab completion more efficient, PowerShell caches the list of namespaces and classnames.

2. Getting Instances

Getting/Enumerating instance of a class is the most commonly performed operation. We wanted the new Get-CimInstance Cmdlet to have better performance and even better user experience as compared to the old Get-WmiObject cmdlet. To achieve these goals we made the following design decisions:

a. The Get-CimInstance cmdlet returns one or more instances of CimInstance. CimInstance is different from the object returned by Get-WmiObject.

b. __Properties are no longer mixed with properties of an instance.

c. Reduce memory and on-the-wire footprint by allowing retrieval of a subset of properties.

3. Working with associations

Working with associations was not straight forward in the old WMI cmdlets. Customers wanted a way to find out associated instances of a particular instance. To resolve this issue we came up with a cmdlet called Get-CimAssociatedInstance. The following example shows some of the important features of this cmdlet.

PS:> $result = Invoke-CimMethod -Query 'SELECT * FROM Win32_Process WHERE name like "notepad%"'

-MethodName GetOwner

# The result has the returned value and out parameters of the method

PS:> $result

5. CliXML serialization.

CimInstance supports full fidelity serialization and deserialization. This is an important feature for those who wish to save state of an instance or result of a cmdlet and then want to use it later. The WMI cmdlets do not support full-fidelity serialization/deserialization.

# CimInstances are serialized and deserialized with full fidelity

PS:> $x = Get-CimInstance Win32_Service

PS:> $x

PS:> $x[0].pstypenames

PS:> $x | Export-CliXml t1.xml

PS:> $y = Import-CliXml .\t1.xml

PS:> $y

PS:> $y[0].pstypenames

# The deserialized objects are identical to the ones obtained from the server

PS:> diff ($y) (Get-CimInstance win32_service )

6. Remote management

Managing remote machines with the new cmdlets is also pretty simple and straight forward. The two parameters that can be used to manage remote machines are:

a. ComputerName

b. CimSession

The following example will explain how these two parameters can be used to manage a remote machine.

PS:> $props = @{v_Key = [UInt64] 8;}

# If ComputerName parameter is used, the cmdlets create an implicit session during the execution.

Tip: If a large number of remote operations are to be performed then session reuse is highly recommended. This can provide a significant performance gain.

7. Easy migration from WMI cmdlets

Last, but not the least, a very important aspect is to reduce learning. If you know how to use WMI cmdlets from PowerShell 2.0, you will find learning new CIM cmdlets easy. These cmdlets follow similar patterns as WMI cmdlets -including parameter names and alias. Let’s see how easy or difficult it is to move to new cmdlets

# OLD: One liner to get ComputerSystem information

PS:> Get-WmiObject Win32_ComputerSystem

# NEW:

PS:> Get-CimInstance Win32_ComputerSystem

# ClassName is position and mandatory.

# Namespace default is root/cimv2 namespace

#WMI Cmdlet – with classnames and Namespace

PS:> Get-WmiObject –ClassName Win32_Process –Namespace root/cimv2

#CIM cmdlet follows the same pattern

PS:> Get-CimInstance –ClassName Win32_Process –Namespace root/cimv2

The table below shows the list of WMI cmdlets and their CIM equivalent:

Old cmdlet

New Cmdlet

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

Note: In old cmdlets Set-WmiInstance was used to perform update and create operations. The new cmdlets clearly define the distinction between the two operations i.e. New-CimInstance is used to create an instance and Set-CimInstance is used to update an existing instance.

You will also notice that in some places we have broken this rule – and script using WMI cmdlet can’t be simply changed to CIM cmdlet by changing the cmdlet name. e.g.

Goal 3 - Support for down-level OS or non-windows machines

CimCmdlets can be used to manage Windows 8, down-level windows machines and any machine that has a CIM standards compliant CIMOM. So, IT pros can now manage non-windows machines with PowerShell in the exact same fashion as they could manage a windows box.

To manage these machines, a CimSession to the machine is required. Once a CimSession is created, the machine can be managed irrespective of the operating system.

WinRM support on down-level windows machines is limited. The latest WMF-V1 release will enable the latest version of WinRM on the down-level machines; this will help our customers in making best use of these new cmdlets.

If customers do not want to install WMF-V1 or do not wish to use WinRM then they can always use DCOM protocol to achieve the same results.

# If ComputerName is specified, WinRM protocol is used

PS:> $serverwin8 = New-CimSession –ComputerName "ServerWin8"

PS:> $serverwin2k8r2 = New-CimSession –ComputerName “Serverwin2k8r2 "

# For a remote machine, if you wish to go over DCOM, you need to explicitly specify