Summary: Guest blogger, Trevor Sullivan, talks about using the CIM module in Windows PowerShell.
Microsoft Scripting Guy, Ed Wilson, is here. Today we have a guest post from Trevor Sullivan. Trevor is an Honorary Scripting Guy, and a recognized Microsoft Community Contributor (MCC). To see more of Trevor’s guest posts, see these Hey, Scripting Guy! Blog posts. You can reach Trevor on Twitter (https://twitter.com/pcgeek86) or follow him on his blog, Trevor Sullivan's Tech Room, Minding the gap between administration and development.
Note This is the second in a series of five posts by Trevor where he will talk specifically about using the CIM cmdlets. Yesterday’s post, What is CIM and Why Should I Use It in PowerShell?, provided a little bit of background on CIM and explained why you will want to use this exciting technology. Today’s post talks about the CIMCmdlets Windows PowerShell module.
Windows PowerShell 3.0, which was first included with Windows Server 2012 and Windows 8.0, introduced a new set of commands as part of a module called CIMCmdlets. The commands contained in the CIMCmdlets module offer several benefits over the legacy WMI cmdlets, including support for auto-completion and the use of the WS-Management remoting protocol.
One of the more obvious usability enhancements in the CIMCmdlets module is the support for auto-completion of WMI namespace names and WMI class names. For example, if you were to use the Get-CimInstance cmdlet to retrieve instances of a WMI class, you can use tab-completion to fill in the values for the -Namespace and -ClassName parameters.
If you attempt the same auto-completion operation by using the Get-WmiObject cmdlet, you will be sorely disappointed. The following image illustrates the way this has been incorporated into IntelliSense in the Windows PowerShell ISE.
Windows Remote Management
Under the hood, the CIMCmdlets module also offers something new that the WMI cmdlets cannot match. That capability is the use of the WS-Management remoting protocol (or WS-Man for short). WS-Management is implemented on the Windows platform through the Windows Remote Management (or WinRM) service. Every Microsoft Windows operating system since Windows 7 has this WinRM service built-in, and all you need to do is enable it. Besides being standards-based, WinRM offers the awesome benefit of predictable network traffic via a single, static port.
When you make outbound connections to the WinRM service, you no longer have to worry about the dynamic port allocation issue that plagued DCOM/RPC. This simple fact will make dealing with security and network engineering personnel much easier, because they will not be required to open a large port range to accommodate DCOM/RPC.
DCOM/RPC can be configured to use a static port since Windows NT 4.0 (for more information, see How to configure RPC dynamic port allocation to work with firewalls). But it’s not a standards-based remoting protocol, and trying to implement such customizations across your entire environment can be challenging, so it’s probably just easier to use WinRM these days.
The CIMCmdlets PowerShell module has several limitations compared the WMI cmdlets.
First of all, most of the CIMCmdlets do not have a -Credential parameter. The only way to specify alternate credentials is to manually build a new CIM session object, and pass that into the -CimSession parameter on the other cmdlets. Due to this missing parameter, you are required to write additional code to provide alternate credentials. If you would like to see a -Credential parameter added in a future version of Windows PowerShell, please vote on this bug in Microsoft Connect: DCR - CIMCmdlets need -Credential parameter.
The next major limitation of the CIMCmdlets is the absence of a number of useful WMI system properties. When you use Get-WmiObject to retrieve a WMI class definition, or an instance of a class, there are several properties that are automatically added. The names of these system properties all start with two underscores (for example: __Derivation). Depending on your Windows PowerShell development goals, you may find this metadata to be useful. If you feel that this should be resolved in a future version of Windows PowerShell, please vote on this bug in Microsoft Connect: DCR - CIM cmdlets not returning WMI metadata.
The last major shortcoming of the CIMCmdlets (that I am aware of) is the lack of WMI methods on .NET objects. When Get-WmiObject was the new kid on the block, static or instance-level WMI methods would be dynamically bound to the .NET object. In CIMCmdlets, the objects retrieved from WMI are not “live,” so you cannot call methods on the .NET object directly. Instead, you must retrieve the CIM instance, and then pass it into the Invoke-CimMethod cmdlet. Unfortunately, this lack of functionality goes against one of the original Windows PowerShell design goals of “discoverability” and being “self-describing.”
That’s all for today! In tomorrow’s post, we will explore the commands in the CIMCmdlets module that you can use to retrieve and manipulate information.
Thank you, Trevor. CIM Week will continue tomorrow when we will have another guest blog post from Trevor.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy