{"id":219,"date":"2014-12-10T00:01:00","date_gmt":"2014-12-10T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/12\/10\/use-powershell-and-wmi-to-explore-threads\/"},"modified":"2019-02-18T10:36:39","modified_gmt":"2019-02-18T17:36:39","slug":"use-powershell-and-wmi-to-explore-threads","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-and-wmi-to-explore-threads\/","title":{"rendered":"Use PowerShell and WMI to Explore Threads"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell and WMI to explore processes and threads.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\" \/>&nbsp;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?<\/p>\n<p>&mdash;CP<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\" \/>&nbsp;Hello CP,<\/p>\n<p>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&mdash;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&mdash;but still, I do miss the interaction. So I have something to look forward today.<\/p>\n<p>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.<\/p>\n<h2>Find the process ID<\/h2>\n<p>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&nbsp;8.1 when I launch the <i>Facebook <\/i>application. I use the <b>Get-CimInstance<\/b> cmdlet to query for the Facebook process. Here is the command I use:<\/p>\n<p style=\"margin-left:30px\">$name = &quot;facebook.exe&quot;<\/p>\n<p style=\"margin-left:30px\">$processHandle = (Get-CimInstance Win32_Process -Filter &quot;Name = &#039;$name&#039;&quot;).ProcessId<\/p>\n<p><b>&nbsp; &nbsp;Note<\/b>&nbsp; I am assuming that there is one instance of a process named <i>facebook.exe. <\/i>If there were multiple processes <br \/>&nbsp; &nbsp;with the same name, I would need to cycle through them.<\/p>\n<h2>Query for threads related to a process<\/h2>\n<p>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 <b>ProcessHandle<\/b> property. In this case, the <b>ProcessHandle<\/b><i> <\/i>property has the same value as the <b>ProcessID<\/b><i> <\/i>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 <b>$threads<\/b>:<\/p>\n<p style=\"margin-left:30px\">$Threads = Get-CimInstance -Class Win32_Thread -Filter &quot;ProcessHandle = $processHandle&quot;&nbsp;<\/p>\n<h2>Produce the output<\/h2>\n<p>As far as output goes, I can do anything I want. Here, I decided to send the output to the <b>Out-GridView<\/b> cmdlet, so that I could filter if I want to. The easy way to do this is to first use the <b>Select-Object<\/b> cmdlet to select the properties I want to display. I decided to produce a custom title on the output from <b>Out-GridView<\/b> by specifying a string value for the <b>&ndash;Title<\/b> parameter. Here is that portion of the script:<\/p>\n<p style=\"margin-left:30px\">$threads | Select-Object priority, thread*, User*Time, kernel*Time |<\/p>\n<p style=\"margin-left:30px\">Out-GridView -Title &quot;The $name process has $($threads.count) threads&quot;<\/p>\n<p>I am simply displaying the output. I could cause the <b>Out-GridView<\/b> 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:<\/p>\n<p style=\"margin-left:30px\">$name = &quot;facebook.exe&quot;<\/p>\n<p style=\"margin-left:30px\">$processHandle = (Get-CimInstance Win32_Process -Filter &quot;Name = &#039;$name&#039;&quot;).ProcessId<\/p>\n<p style=\"margin-left:30px\">$Threads = Get-CimInstance -Class Win32_Thread -Filter &quot;ProcessHandle = $processHandle&quot;<\/p>\n<p style=\"margin-left:30px\">$threads | Select-Object priority, thread*, User*Time, kernel*Time |<\/p>\n<p style=\"margin-left:30px\">Out-GridView -Title &quot;The $name process has $($threads.count) threads&quot;<\/p>\n<p>The GridView control produced by the script is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-12-10-14-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-12-10-14-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>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.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell and WMI to explore processes and threads. &nbsp;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? &mdash;CP &nbsp;Hello CP, Microsoft [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[385,31,485,3,4,45],"class_list":["post-219","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-cim","tag-operating-system","tag-process","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell and WMI to explore processes and threads. &nbsp;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? &mdash;CP &nbsp;Hello CP, Microsoft [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/219","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=219"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/219\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=219"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=219"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=219"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}