{"id":13131,"date":"2011-08-02T00:01:00","date_gmt":"2011-08-02T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/08\/02\/use-the-powershell-select-string-cmdlet-to-parse-wmi-output\/"},"modified":"2011-08-02T00:01:00","modified_gmt":"2011-08-02T00:01:00","slug":"use-the-powershell-select-string-cmdlet-to-parse-wmi-output","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-the-powershell-select-string-cmdlet-to-parse-wmi-output\/","title":{"rendered":"Use the PowerShell Select-String Cmdlet to Parse WMI Output"},"content":{"rendered":"<p><strong>Summary<\/strong>: Learn how to use the Windows PowerShell Select-String cmdlet to easily parse WMI output.<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\" \/>Hey, Scripting Guy! I have a quick question: is it possible to parse the output of some of the WMI commands? I know they return objects, but some of the commands return sooooo much data. I would like a quick and easy way to look for specific things such as errors or failures, without a lot of fuss and muss. Is this possible?<\/p>\n<p>&mdash;DD<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\" \/>Hello DD,<\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. And, yes, it is possible. When working with WMI classes, I normally use the <b>Where-Object<\/b> cmdlet to perform a filter, or I will use WMI itself to perform the filter. In general, if I am working interactively from the Windows PowerShell prompt, my first choice is to use the <b>Where-Object<\/b> cmdlet (the alias is <b>?<\/b>) simply because it is more natural to me and is easier to type. But it is not as fast. For example, if I am working with the <b>Win32_ReliabilityRecords<\/b> WMI class, it can return a lot of data. If I am only looking for status messages that contain the word <i>failed<\/i> in them, I might pipe the results to the <b>Where-Object<\/b> cmdlet. The command is shown here (<b>gwmi<\/b> is the alias for the <b>Get-WmiObject<\/b> cmdlet, and <b>?<\/b> is the alias for the <b>Where-Object<\/b> cmdlet):<\/p>\n<p style=\"padding-left: 30px\">gwmi win32_reliabilityrecords | ? { $_.message -match &#8220;failed&#8221; }<\/p>\n<p>The command and the associated output are shown here.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6201.hsg-8-2-11-1.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of command and associated output\" alt=\"Image of command and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6201.hsg-8-2-11-1.jpg\" \/><\/a><\/p>\n<p>As you can see in the preceding figure, a lot of information is returned. These are all objects, so I have the opportunity to do additional processing, if I want to do so. However, what if I do not want to do additional processing? In fact, what if all I want to do is see messages that contained the word <i>failed<\/i> in them? In this case, I might turn to the <b>Select-String<\/b> cmdlet. The syntax of such a command is shown following this paragraph. This command uses the <b>gwmi<\/b> alias for the <b>Get-WmiObject<\/b> cmdlet. There is no default alias for the <b>Select-String<\/b> cmdlet. In <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/08\/01\/use-the-powershell-grep-command-to-parse-the-command-line.aspx\">yesterday&rsquo;s Hey, Scripting Guy! Blog post<\/a>, I showed how to create an alias called <b>grep<\/b> to make it easier to use the <b>Select-String<\/b> cmdlet from an interactive Windows PowerShell prompt.<\/p>\n<p style=\"padding-left: 30px\">gwmi win32_reliabilityrecords | select-string &#8220;failed&#8221; -InputObject {$_.message}<\/p>\n<p>The command and associated output are shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3652.hsg-8-2-11-2.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of command and associated output\" alt=\"Image of command and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3652.hsg-8-2-11-2.jpg\" \/><\/a><\/p>\n<p>As shown in the preceding figure, the output is much more succinct and easier to read. So how does the command work? I use the <b>Get-WmiObject<\/b> cmdlet to query for all records from the Reliability Provider. The Reliability Provider supports the <b>Win32_ReliabilityRecords<\/b> WMI class. I pipe all of these records to the <b>Select-String<\/b> cmdlet. The <b>Select-String<\/b> cmdlet uses the pattern <b>&ldquo;failed&rdquo;<\/b> and searches each incoming <b>message<\/b> property. Here is the trick: I must use curly brackets along with the <b>$_<\/b> automatic variable to read inside the <b>message<\/b> property. Normally I would use simple parentheses to force the evaluation, but that does not work here. Leaving the <b>inputobject<\/b> value unadorned does not work either.<\/p>\n<p>What about speed? I decided to use the <b>Measure-Command<\/b> cmdlet to measure the performance of the two commands. The two commands are shown here:<\/p>\n<p style=\"padding-left: 30px\">measure-command {gwmi win32_reliabilityrecords | ? { $_.message -match &#8220;failed&#8221; } }<\/p>\n<p style=\"padding-left: 30px\">measure-command {gwmi win32_reliabilityrecords | select-string &#8220;failed&#8221; -InputObject {$_.message} }<\/p>\n<p>As seen in the following figure, the first command (using the <b>Where-Object <\/b>cmdlet) takes about 10.1 seconds. The second command (using the <b>Select-String<\/b> cmdlet) takes about 10.5 seconds. So the first command is a bit faster.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2475.hsg-8-2-11-3.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of speed of each command\" alt=\"Image of speed of each command\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2475.hsg-8-2-11-3.jpg\" \/><\/a><\/p>\n<p>Unfortunately, the WMI Reliability Provider does not appear to support the WMI <b>like<\/b> operator. Therefore, the following command fails.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; gwmi win32_reliabilityrecords -filter &#8220;message -like &#8216;%failed%'&#8221;<\/p>\n<p style=\"padding-left: 30px\">Get-WmiObject : Invalid query<\/p>\n<p style=\"padding-left: 30px\">At line:1 char:5<\/p>\n<p style=\"padding-left: 30px\">+ gwmi &lt;&lt;&lt;&lt;&nbsp; win32_reliabilityrecords -filter &#8220;message -like &#8216;%failed%'&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : InvalidOperation: (:) [Get-WmiObject], ManagementException<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObject Command<\/p>\n<p>By selecting only the <b>message<\/b> property, the query speeds a little. The output is better formatted as well:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; gwmi win32_reliabilityrecords -Property message | ? {$_.message -match &#8220;failed&#8221; }&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">__GENUS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2<\/p>\n<p style=\"padding-left: 30px\">__CLASS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Win32_ReliabilityRecords<\/p>\n<p style=\"padding-left: 30px\">__SUPERCLASS&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__DYNASTY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__RELPATH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__PROPERTY_COUNT : 1<\/p>\n<p style=\"padding-left: 30px\">__DERIVATION&nbsp;&nbsp;&nbsp;&nbsp; : {}<\/p>\n<p style=\"padding-left: 30px\">__SERVER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__NAMESPACE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__PATH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">Message&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Installation Failure: Windows failed to install the following update with error<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x80070643: Definition Update for Windows Defender &#8211; KB915597 (Definition 1.99.1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 460.0).<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">__GENUS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2<\/p>\n<p style=\"padding-left: 30px\">__CLASS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Win32_ReliabilityRecords<\/p>\n<p style=\"padding-left: 30px\">__SUPERCLASS&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__DYNASTY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__RELPATH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__PROPERTY_COUNT : 1<\/p>\n<p style=\"padding-left: 30px\">__DERIVATION&nbsp;&nbsp;&nbsp;&nbsp; : {}<\/p>\n<p style=\"padding-left: 30px\">__SERVER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__NAMESPACE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">__PATH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">Message&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Installation Failure: Windows failed to install the following update with error<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x80070643: Definition Update for Microsoft Forefront code named Stirling Beta v<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ersion &#8211; KB977939 (Definition 1.95.257.0).<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p>The time of the previous query is shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; Measure-command {gwmi win32_reliabilityrecords -Property message | ? {$_.message -match &#8220;failed&#8221;} }&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Days&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;: 0<\/p>\n<p style=\"padding-left: 30px\">Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 8<\/p>\n<p style=\"padding-left: 30px\">Milliseconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 911<\/p>\n<p style=\"padding-left: 30px\">Ticks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 89110704<\/p>\n<p style=\"padding-left: 30px\">TotalDays&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.000103137388888889<\/p>\n<p style=\"padding-left: 30px\">TotalHours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.00247529733333333<\/p>\n<p style=\"padding-left: 30px\">TotalMinutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.14851784<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 8.9110704<\/p>\n<p style=\"padding-left: 30px\">TotalMilliseconds : 8911.0704<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p>If I want to return only the <b>message<\/b> property and not the WMI System properties, I can pipe the results to the <b>Select-Object<\/b> cmdlet and choose only the <b>message<\/b> property. This command and associated output are shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; gwmi win32_reliabilityrecords -Property message | ? {$_.message -match &#8220;failed&#8221; } | select message&nbsp;<\/p>\n<p style=\"padding-left: 30px\">message<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;-<\/p>\n<p style=\"padding-left: 30px\">Installation Failure: Windows failed to install the following update with error 0x80070643: Defi&#8230;<\/p>\n<p style=\"padding-left: 30px\">Installation Failure: Windows failed to install the following update with error 0x80070643: Defi&#8230;<\/p>\n<p>&nbsp;<\/p>\n<p>As can be seen above, however, the <b>message<\/b> field is truncated. Therefore, to display the entire message property, it is necessary to use the <i>expandproperty <\/i>parameter. This is shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; gwmi win32_reliabilityrecords -Property message | ? {$_.message -match &#8220;failed&#8221; } | select &#8211;<\/p>\n<p style=\"padding-left: 30px\">ExpandProperty message<\/p>\n<p style=\"padding-left: 30px\">Installation Failure: Windows failed to install the following update with error 0x80070643: Definit<\/p>\n<p style=\"padding-left: 30px\">ion Update for Windows Defender &#8211; KB915597 (Definition 1.99.1460.0).<\/p>\n<p style=\"padding-left: 30px\">Installation Failure: Windows failed to install the following update with error 0x80070643: Definit<\/p>\n<p style=\"padding-left: 30px\">ion Update for Microsoft Forefront code named Stirling Beta version &#8211; KB977939 (Definition 1.95.257<\/p>\n<p style=\"padding-left: 30px\">.0).<\/p>\n<p>At this point, it is a bit faster and certainly easier to go back to using the <b>Select-String<\/b> cmdlet. It might make sense to modify it to return only the <b>message<\/b> property. This revised command and associated output are shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; gwmi win32_reliabilityrecords -property message | select-string &#8220;failed&#8221; -InputObject {$_.me<\/p>\n<p style=\"padding-left: 30px\">ssage}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Installation Failure: Windows failed to install the following update with error 0x80070643: Definit<\/p>\n<p style=\"padding-left: 30px\">ion Update for Windows Defender &#8211; KB915597 (Definition 1.99.1460.0).<\/p>\n<p style=\"padding-left: 30px\">Installation Failure: Windows failed to install the following update with error 0x80070643: Definit<\/p>\n<p style=\"padding-left: 30px\">ion Update for Microsoft Forefront code named Stirling Beta version &#8211; KB977939 (Definition 1.95.257<\/p>\n<p style=\"padding-left: 30px\">.0).<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;<\/p>\n<p>Well, DD, that is about all there is to using the <b>Select-String<\/b> cmdlet to parse WMI data. Join me tomorrow when we will continue our discussion about parsing output.<\/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\">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><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Learn how to use the Windows PowerShell Select-String cmdlet to easily parse WMI output. &nbsp; Hey, Scripting Guy! I have a quick question: is it possible to parse the output of some of the WMI commands? I know they return objects, but some of the commands return sooooo much data. I would like a [&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":[3,4,281,45,77],"class_list":["post-13131","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-select-string","tag-windows-powershell","tag-writing"],"acf":[],"blog_post_summary":"<p>Summary: Learn how to use the Windows PowerShell Select-String cmdlet to easily parse WMI output. &nbsp; Hey, Scripting Guy! I have a quick question: is it possible to parse the output of some of the WMI commands? I know they return objects, but some of the commands return sooooo much data. I would like a [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13131","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=13131"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13131\/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=13131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=13131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=13131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}