Prof. Powershell

WMI CIM-plified Part 5: WSMAN Protocol

Next up in Jeff's six-part WMI series, he demonstrates how to call up WMI methods.

In PowerShell 3.0, the new CIM cmdlets use the WSMAN protocol to retrieve WMI information. A byproduct is that the objects you retrieve across the wire do not have any WMI methods. Using WMI, we would have done something like this:

PS C:\> calc
PS C:\> $p = get-wmiobject win32_process -filter "name='calc.exe'" –comp client8
PS C:\> $p.Terminate()

But that won't work with the CIM cmdlets.

PS C:\> $p = get-ciminstance win32_process -filter "name='calc.exe'" –comp client8
PS C:\> $p.terminate()

You will get an exception complaining that [Microsoft.Management.Infrastructure.CimInstance] doesn't contain a method named 'terminate'. What we need to do is use the Invoke-CimMethod cmdlet. This works in much the same way as Invoke-WmiMethod with one major exception which I'll cover in a moment.

Personally, I find the best approach is to pipe the CIM object to the cmdlet.

PS C:\> $p | Invoke-CimMethod -MethodName terminate

You will still get a result object with a ReturnValue property. The cmdlet also supports –WhatIf and –Confirm for added safety.

PS C:\> invoke-cimmethod -CimSession $t -Query "Select * from win32_process where name='calc.exe'" -MethodName terminate -whatif
What if: Performing operation "Invoke-CimMethod: terminate" on Target "Win32_Pro
cess: calc.exe (Handle = "2308")".

In this example I used a previously created CIM Session and a syntax variation to find all instances of calculator.

This example is relatively simple because the method doesn't require any parameters. But WMI methods that do require parameters are notoriously difficult to use. You need to get the parameters in the right order and account for values you want to ignore. Invoke-CimMethod makes this much easier because all we need to do is pass a hash table of the parameter values we want to change.

Here's an example. First, I'll get a service.

PS C:\> $svc = get-ciminstance win32_service -filter "name='bits'"

I want to change the service account and password. This requires using the Change() method which has a number of parameters you have to get in the right order if using WMI techniques. But with CIM, it is much, much easier.

PS C:\> $svc | Invoke-CimMethod -Name change -Arguments @{Startname=".\administrator";StartPassword="P@ssw0rd"}

All I need to do is specify the parameters I need to change. So much easier than using WMI. Now, if you try this example on a test system as I did, you might get an error. Which is fine because it proves that the change was made. All I really wanted to demonstrate was the technique. Hopefully your need to call WMI methods is more of an exception than the rule.

I hope this has piqued your interest in the world of the CIM cmdlets. Fire up your test network and give them a try. There's more information in the book PowerShell in Depth and if you really get stuck, please pop in to the forums at PowerShell.org.

 

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular