Summary: Guest blogger, Trevor Sullivan, talks about invoking CIM methods via Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. Today we have another 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.

     Note  This is the fourth in a series of five posts by Trevor where he talks specifically about using the CIM cmdlets.
     To catch up, read the following posts:

Here’s Trevor…

In yesterday’s post, we talked about reading and writing CIM properties. Today, we’ll look at WMI/CIM methods.

In the context of programming terminology, methods generally represent actions that you can perform against an object. In CIM/WMI, this is no exception. Similar to properties, methods can be declared as static or instance methods. Static methods are declared on a class, and generally don’t operate on any particular instance of that class. Instance methods are generally actions that are performed against a specific instance of the class.

Classes are blueprints of an object that do not represent an instance of the object itself. For example, think of a car blueprint. The blueprint represents what a car might look like, how many wheels it has, how many doors it has, the size of the engine, what type of transmission it has, and so on. Blueprints are not actual cars, however. Therefore, a static method might be defined at the class (blueprint) level called Build(), which produces a car.

Instance methods generally operate on an instance of the class that declares the method. To get an instance of a car, you must first call the blueprint’s Build() method. When you have a specific car (instance) that is built according to the blueprint’s (class) specifications, you could begin calling instance-level methods on it.

On any given car instance, you might have a method called Drive(), which causes the car to move. Similarly, you might have an OpenHood() method, which opens the hood of the vehicle. Because these methods operate on a specific car, they are better declared at the instance (specific car) level as opposed to the class (blueprint) level.

Moving from the car example to a software example, you could have a class called Process. This class does not represent a specific process (such as svchost.exe or iexplore.exe), but rather, it defines a blueprint for what a process looks like.

In CIM/WMI, there is in fact a class called Win32_Process that exists in the root\cimv2 WMI namespace. This class has a static (blueprint) method called Create(), which allows you to create (start) a process in a Windows operating system. After you have a process, you have the ability to terminate the process using the Terminate() method. The Terminate() method is an instance-level method because the action of terminating is performed against a specific process.

Calling an instance method

Here is some sample script that shows how to call the Win32_Process.Terminate() CIM method by using the new Invoke-CimMethod cmdlet. This method call is particularly easy because we do not have to specify any method parameters.

# Start a new instance of notepad.exe

notepad;

# Retrieve the Win32_Process instance for notepad.exe

$Notepad = Get-CimInstance -ClassName Win32_Process -Filter "Name = 'notepad.exe'";

# Invoke the Win32_Process.Terminate() method

Invoke-CimMethod -InputObject $Notepad -MethodName Terminate;

Calling a static method

Static methods can be called easily also. Let’s take a look at the Win32_Process.Create() method, which creates a new process. The Create() method is different from Terminate() because it requires that we pass method parameters to it, specifically the path to the process that we want to start. How do we know what those parameters are?

Let’s first look at a list of CIM methods that are available for the Win32_Process class:

(Get-CimClass -ClassName Win32_Process).CimClassMethods;

Then, let’s narrow things down specifically to the Create() method:

(Get-CimClass -ClassName Win32_Process).CimClassMethods['Create'].Parameters;

Now we can see a list of all the method parameters that Create() requires:

Image of command output

To use Invoke-CimMethod to call the Create() method, we need to create a HashTable of parameters to pass into it.

$Arguments = @{

    CommandLine = 'notepad.exe';

    CurrentDirectory = $null;

    ProcessStartupInformation = $null;

};

Then, we can call the method.

Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments $Arguments;

When you run the previous script on a local computer, you should see notepad.exe running. You might wonder why we left out the ProcessId parameter when we started the process. The reason is that the process ID is an “out” parameter, which is returned to us when the process is launched. We do not need to pass a ProcessId into the Create() method, because that simply doesn’t make sense.

Limitations

A couple of days ago, I briefly mentioned how WMI methods are not bound to the .NET objects, when you use the CIMCmdlets PowerShell module. Let’s take a look at how things have changed from the traditional WMI days.

One relatively common task that is performed through WMI is terminating processes, which we explored earlier in this post. If you want to terminate a process by using WMI, you could simply call the appropriate WMI method on the WMI object that you received from the Get-WmiObject cmdlet:

(Get-WmiObject -Class Win32_Process -Filter "Name = 'notepad.exe'").Terminate();

If you want to call a static method on a class, such as the Create() method on the Win32_Process class, you could use the [wmiclass] type accelerator to get a reference to the class, and then call the static method by using the dot/period operator:

([wmiclass]"root\cimv2:Win32_Process").Create('notepad.exe');

If you called the method without any parameters and sans the parentheses, Windows PowerShell used to show you the WMI method signature. Unfortunately, you now have to use a bit more effort to figure out the method signature by using an external GUI tool, or by using the Get-CimClass cmdlet, as previously demonstrated.

Well, that’s all for today! We’ll wrap things up tomorrow by looking at CIM sessions and Windows PowerShell sessions.

~Trevor

That is all there is to invoking CIM methods. CIM Week will continue tomorrow when Trevor will talk about CIM sessions and PS Remoting.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy