Learn Four Ways to Kill a Process Using PowerShell and WMI

Summary: Microsoft Scripting Guy Ed Wilson shows four ways to kill a process by using Windows PowerShell and WMI.

Hey, Scripting Guy! I have been playing around with your scripts that explore WMI methods and WMI writable properties, but I am having problems calling the WMI methods. Can you help me?

—ET

Hello ET,

Microsoft Scripting Guy, Ed Wilson, is here. The Scripting Wife and I are super excited! Tomorrow night (August 9, 2011) we are going to appear at the Corpus Christi PowerShell User Group in Corpus Christi, Texas. This is their first meeting, and we hope to get them started out right. The group president, Mark Adam Carter, has been really busy getting everything set up for this meeting. If you are in the neighborhood, plan on stopping by. It will be a great meeting!

I wrote that series of articles you refer to as leadup to the 2011 Scripting Games. The series itself consisted of four articles:

ET, phone home. Just kidding. ET, the listing of all methods and writable properties from all WMI classes is a very good place to start, if you are looking to call some WMI methods. One reason for this is that the available classes varies from version to version of the operating system. In addition, the available classes will vary depending on which options are installed. The other thing to keep in mind is that some classes have added additional methods to classes in later versions of the operating system. Examples of this are the Enable and Disable methods that are available in the Win32_NetworkAdapter WMI class. These methods were added to Windows Vista. I wrote about these methods in How Can I Enable or Disable My Network Adapter? blog post.

There are actually several ways to call WMI methods in Windows PowerShell. One reason for this is that some WMI methods are instance methods, which means they only work on an instance of the class. Other methods are static methods, which means they do not operate on an instance of the class. For example, the Terminatemethod from the Win32_Process class is an instance method—it will operate only against a specific instance of the Win32_Process. If I do not have a reference to a process, I cannot terminate the process. On the other hand, if I want to createa new instance of a Win32_Process class, I do not grab a reference to an instance of the class. For example, I do not grab an instance of Calculator to create an instance of Notepad. Therefore, I need a static method that is always available.

ET, let me illustrate the first of these two principles—instance methods and static methods—with a short example (I will talk about static methods tomorrow). First, I create an instance of Notepad. I then use the Get-Process cmdlet to view the process (gps is an alias for the Get-Process cmdlet). This is shown here:

PS C:\> notepad

PS C:\> Get-WmiObject win32_process -Filter "name = 'notepad.exe'"

__GENUS : 2

__CLASS : Win32_Process

__SUPERCLASS : CIM_Process

__DYNASTY : CIM_ManagedSystemElement

__RELPATH : Win32_Process.Handle="588"

__PROPERTY_COUNT : 45

__DERIVATION : {CIM_Process, CIM_LogicalElement, CIM_ManagedSyste

mElement}

__SERVER : NEWMRED

__NAMESPACE : root\cimv2

__PATH : \\NEWMRED\root\cimv2:Win32_Process.Handle="588"

Caption : notepad.exe

CommandLine : "C:\Windows\system32\notepad.exe"

CreationClassName : Win32_Process

CreationDate : 20110802191720.281486-240

CSCreationClassName : Win32_ComputerSystem

CSName : NEWMRED

Description : notepad.exe

ExecutablePath : C:\Windows\system32\notepad.exe

ExecutionState :

Handle : 588

HandleCount : 61

InstallDate :

KernelModeTime : 156001

MaximumWorkingSetSize : 1380

MinimumWorkingSetSize : 200

Name : notepad.exe

OSCreationClassName : Win32_OperatingSystem

OSName : Microsoft Windows 7 Ultimate |C:\Windows|\Device\H

arddisk0\Partition2

OtherOperationCount : 67

OtherTransferCount : 198

PageFaults : 1362

PageFileUsage : 1972

ParentProcessId : 6324

PeakPageFileUsage : 1972

PeakVirtualSize : 72261632

PeakWorkingSetSize : 5308

Priority : 8

PrivatePageCount : 2019328

ProcessId : 588

QuotaNonPagedPoolUsage : 7

QuotaPagedPoolUsage : 149

QuotaPeakNonPagedPoolUsage : 7

QuotaPeakPagedPoolUsage : 150

ReadOperationCount : 0

ReadTransferCount : 0

SessionId : 1

Status :

TerminationDate :

ThreadCount : 1

UserModeTime : 0

VirtualSize : 72261632

WindowsVersion : 6.1.7601

WorkingSetSize : 5435392

WriteOperationCount : 0

WriteTransferCount : 0

ProcessName : notepad.exe

Handles : 61

VM : 72261632

WS : 5435392

Path : C:\Windows\system32\notepad.exe

After I have the instance of the notepad process I want to terminate, I have at least four choices:

I can call the method directly using dotted notation (because there is only one instance of the notepad process).

I can store the reference in a variable, and then terminate it directly.

I can use the Invoke-WMIMethod cmdlet.

I can use the [WMI] type accelerator.

You will notice that each time the method is called, a ReturnValue property is returned from the method call. This value is used to determine if the method completed successfully. Return codes are documented for the Terminate method on MSDN (each method will have its return codes detailed on MSDN):

If I want to use the Windows PowerShell Invoke-WMIMethod cmdlet to call an instance method, I must pass a path to the instance to be operated upon. The easiest way to obtain the path to the instance is to first perform a WMI query, and then use the __RelPath system property. The __RelPath system property contains the relative path to the instance of the class. This is shown here:

If I am working against a remote machine, I will want the complete path to the instance. The complete path includes the computer name, the WMI namespace, and the class and the key to the class. The complete path is shown in the __Path system property as shown here (do not get confused—the Win32_Process WMI class also contains a path property):

PS C:\> $a.__path

\\NEWMRED\root\cimv2:Win32_Process.Handle="5676"

As shown here, I first create an instance of the notepad process, use the Get-WmiObject cmdlet to retrieve that instance of the process, display the value of the __RELPATH property, and then call the Invoke-WmiMethod cmdlet. When calling the Invoke-WmiMethod cmdlet, I pass the path to the instance and the name of the method to utilize. This is shown in the following commands:

Another way to call an instance method is to use the [WMI] type accelerator, which works with WMI instances. Therefore, if I pass a path to the [WMI] type accelerator, I can call instance methods directly. In the example that appears here, I start an instance of the notepad process. Next, I use the Get-WmiObject cmdlet to retrieve all instances (there is only one instance) of notepad. Next, I pass the value of the __RELPATH system property to the [WMI] type accelerator. This command returns all of the properties associated with Win32_Process (the same properties seen earlier in this article) for the specific instance of Win32_Process that is indicated by the __RelPath system property. I therefore select only the name property from the object. To this point, I have illustrated that I can retrieve a specific instance of a Win32_Process WMI class via the [WMI] type accelerator. Therefore, it is time to call the Terminate method. This technique is shown here: