Use PowerShell and WMI to Explore Threads


Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell and WMI to explore processes and threads.

Hey, Scripting Guy! Question Hey, Scripting Guy! I need to find information about threads that are related to a specific process. I am wondering how I can do this by using Windows PowerShell. Can you help me?

—CP

Hey, Scripting Guy! Answer Hello CP,

Microsoft Scripting Guy, Ed Wilson, is here. This morning I have a couple of meetings. I like meetings because it is a great chance to interact with other people from Microsoft—and that is always a good thing when one works from home. It is one of the things I miss most about working on campus. Of course, working remotely has a number of advantages, such as getting a whole lot more work done in a given period of time—but still, I do miss the interaction. So I have something to look forward today.

Well CP, threads are sort of like meetings in that one process can spawn numerous threads and one meeting often spawns other meetings. The trick is keeping track of everything.

Find the process ID

The first thing I need to do is to find a way to keep track of everything. Every process has a process ID, and I can find it by using the Win32_Process WMI class. I can also filter by the name of the process. For an example, I am going to use the facebook.exe process that starts on my laptop running Windows 8.1 when I launch the Facebook application. I use the Get-CimInstance cmdlet to query for the Facebook process. Here is the command I use:

$name = "facebook.exe"

$processHandle = (Get-CimInstance Win32_Process -Filter "Name = '$name'").ProcessId

   Note  I am assuming that there is one instance of a process named facebook.exe. If there were multiple processes
   with the same name, I would need to cycle through them.

Query for threads related to a process

To query for threads, I use the Win32_Thread WMI class. There are hundreds of threads running on a computer at any given time, and so this can be a rather expensive WMI query. To reduce the impact of the WMI query, I filter by the ProcessHandle property. In this case, the ProcessHandle property has the same value as the ProcessID I obtained in the previous query. I can therefore filter out threads by using this process ID. As shown here, I store the results of the query in a variable I call $threads:

$Threads = Get-CimInstance -Class Win32_Thread -Filter "ProcessHandle = $processHandle" 

Produce the output

As far as output goes, I can do anything I want. Here, I decided to send the output to the Out-GridView cmdlet, so that I could filter if I want to. The easy way to do this is to first use the Select-Object cmdlet to select the properties I want to display. I decided to produce a custom title on the output from Out-GridView by specifying a string value for the –Title parameter. Here is that portion of the script:

$threads | Select-Object priority, thread*, User*Time, kernel*Time |

Out-GridView -Title "The $name process has $($threads.count) threads"

I am simply displaying the output. I could cause the Out-GridView cmdlet to pause, and then I could select specific items in the output pane and send the selected output back to the Windows PowerShell console. In this way, I could kill processes that had too many threads in a wait state (for example). Here is my complete script:

$name = "facebook.exe"

$processHandle = (Get-CimInstance Win32_Process -Filter "Name = '$name'").ProcessId

$Threads = Get-CimInstance -Class Win32_Thread -Filter "ProcessHandle = $processHandle"

$threads | Select-Object priority, thread*, User*Time, kernel*Time |

Out-GridView -Title "The $name process has $($threads.count) threads"

The GridView control produced by the script is shown here:

Image of command output

CP, that is all there is to using Windows PowerShell and WMI to find thread information. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.

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 

Comments (0)

Skip to main content