{"id":54253,"date":"2009-03-05T21:20:00","date_gmt":"2009-03-05T21:20:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/03\/05\/hey-scripting-guy-how-can-i-get-wmi-information-about-more-than-one-computer\/"},"modified":"2009-03-05T21:20:00","modified_gmt":"2009-03-05T21:20:00","slug":"hey-scripting-guy-how-can-i-get-wmi-information-about-more-than-one-computer","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-get-wmi-information-about-more-than-one-computer\/","title":{"rendered":"Hey, Scripting Guy! How Can I Get WMI Information About More Than One Computer?"},"content":{"rendered":"<p><H2><IMG class=\"nearGraphic\" 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\"> <\/H2>\n<P>I want to tell you that I love your articles. I have learned more about tea in the last three months than I ever thought was possible. In fact, if truth be told, I never thought about tea that much. I do like the can of tea from the vending machine, if that counts. Sometimes I drink that instead of soda pop, when I want to get the healthy antioxidants. To be honest, I am not sure what an antioxidant is, but I am sure I need a few every now and then. Anyway, I have a problem. All your scripts on the Script Center basically run against one computer\u2014and like, man, if we only had one computer, I do not think I would need to be running scripts. How about showing me how to obtain WMI information from more than one computer?<BR><BR>&#8211; HM<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" 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\"> \n<P>Hi HM,<\/P>\n<P><A href=\"http:\/\/encarta.msn.com\/encyclopedia_761595946\/Antioxidant.html\" target=\"_blank\">Antioxidants<\/A> help fight free radicals, which by the way have nothing to do with <A href=\"http:\/\/encarta.msn.com\/encyclopedia_762505913\/Hippie.html#p1\" target=\"_blank\">hippies<\/A>. Antioxidants are found in lots of fruits, as well as in tea (green, black, and even white). So you are probably safe with your canned tea. <\/P>\n<P>There are many ways that a script can be written to run against multiple computers. For some simple tasks, you can use <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/tools\/scripto2.mspx\" target=\"_blank\">Scriptomatic 2.0<\/A>. It can accept text input or an array of computer names. We also have some tips in the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/scripts\/misc\/default.mspx\" target=\"_blank\">scripting techniques section<\/A> of the Script Repository. Most of the time, the addition of the code complicates a script, so it is left off for demonstration purposes.<\/P>\n<TABLE id=\"EJD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">This week we will be looking at working with WMI from within Windows PowerShell. In honor of this week, we have created <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/wmi.mspx\">a new WMI Scripting Hub<\/A> that pulls together a number of useful articles and tools from all over the Script Center into a single location. Because the articles will be using Windows PowerShell, you may also be interested in the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\">Windows PowerShell Scripting Hub<\/A>. You will find information there that will tell you how to download and install Windows PowerShell. <\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Here is one such script called <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/scripts\/misc\/input\/msinvb01.mspx\" target=\"_blank\"><B>ReadArgumentsFromText.vbs<\/B><\/A>. It is taken from the scripting techniques section of the Script Center Script Repository:<\/P><PRE class=\"codeSample\">Const ForReading = 1<\/p>\n<p>Set objDictionary = CreateObject(&#8220;Scripting.Dictionary&#8221;)\nSet objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objTextFile = objFSO.OpenTextFile(&#8220;c:\\fso\\servers.txt&#8221;, ForReading)\ni = 0<\/p>\n<p>Do Until objTextFile.AtEndOfStream \n    strNextLine = objTextFile.Readline\n    objDictionary.Add i, strNextLine\n    i = i + 1\nLoop<\/p>\n<p>For Each objItem in objDictionary\n    Set colServices = GetObject(&#8220;winmgmts:\/\/&#8221; &amp; _\n        objDictionary.Item(objItem) _\n            &amp; &#8220;&#8221;).ExecQuery(&#8220;Select * from Win32_Service&#8221;)\n    Wscript.Echo colServices.Count\nNext\n<\/PRE>\n<P>The <B>ReadArgumentsFromText.vbs<\/B> script reads a text file named <B>Servers.txt<\/B> from the <B>C:\\Fso<\/B> folder. The <B>Servers.txt<\/B> file is seen in the image following this paragraph, and as you can tell it is a simple text file with the name of a separate server on each line:<\/P><IMG border=\"0\" alt=\"Image of the Servers.txt file\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/march\/hey0305\/hsg-3-5-9-1.jpg\" width=\"336\" height=\"198\"> \n<P>&nbsp;<\/P>\n<P>To read a text file using Windows PowerShell, we can use the <B>Get-Content<\/B> cmdlet and specify the path to the text file. The content of the text file is returned as an array of text. This is illustrated by indexing into the returned array and retrieving the data in the third line of the text file. This is seen here.<\/P><PRE class=\"codeSample\">PS C:\\&gt; (Get-Content -Path C:\\fso\\Servers.txt)[2]\nLocalHost\n<\/PRE>\n<P>Once we have the array of text from the file, we pipeline it to the <B>ForEach-Object<\/B> cmdlet. The <B>ForEach-Object<\/B> cmdlet works similar to a <B>For\u2026Each\u2026Next<\/B> type of construction from VBScript. It provides access to each item as it comes across the array via the automatic variable <B>$_<\/B>. This allows us to work with each item as it comes across the pipeline. This is illustrated here where we take an array of computer names and pipeline them to the <B>ForEach-Object<\/B> cmdlet. Inside the code block (the curly brackets <B>{}<\/B>) we use the <B>$_<\/B> automatic variable to print out each item in the array:<\/P><PRE class=\"codeSample\">PS C:\\&gt; &#8220;berlin&#8221;,&#8221;Vista&#8221;,&#8221;LocalHost&#8221; | Foreach-Object { $_ }\nberlin\nVista\nLocalHost\n<\/PRE>\n<P>The semicolon is used to separate commands in Windows PowerShell in the same way it is done in VBScript. What I want to do is to print out a message that says I am querying the computer, and then use the <B>Get-WmiObject<\/B> cmdlet to query the computer. We are retrieving BIOS information from the <B>Win32_Bios<\/B> WMI class. The <B>\u2013computername<\/B> parameter is used to allow us to query a remote computer. The basic WMI query is seen here, where we retrieve BIOS information from the <B>Win32_Bios<\/B> WMI class from a remote computer named <B>Berlin<\/B><B>:<\/B><\/P><PRE class=\"codeSample\">PS C:\\&gt; Get-WmiObject -Class win32_bios -ComputerName berlin<\/p>\n<p>SMBIOSBIOSVersion : 080002\nManufacturer      : American Megatrends Inc.\nName              : BIOS Date: 02\/22\/06 20:54:49  Ver: 08.00.02\nSerialNumber      : 2096-1160-0447-0846-3027-2471-99\nVersion           : A M I  &#8211; 2000622\n<\/PRE>\n<P>The complete one-line command that reads the text file and queries each computer for the BIOS information is seen here:<\/P><PRE class=\"codeSample\">Get-Content -Path C:\\fso\\Servers.txt | \nForEach-Object { &#8220;Querying $_&#8221; ;Get-WmiObject -Class Win32_bios -ComputerName $_ }\n<\/PRE>\n<P>When we run the above command, we receive the results seen here:<\/P><IMG border=\"0\" alt=\"Image of the results of running the command\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/march\/hey0305\/hsg-3-5-9-2.jpg\" width=\"668\" height=\"559\"> \n<P>&nbsp;<\/P>\n<P>If the syntax shown above is too long, it can be shortened considerably through the use of aliases and positional arguments:<\/P><PRE class=\"codeSample\">gc C:\\fso\\Servers.txt | % { &#8220;Querying $_&#8221; ; gwmi win32_bios -co $_ }<\/PRE>\n<P><B>Gc<\/B> is an alias for the <B>Get-Content<\/B> cmdlet. The default argument for the <B>Get-Content<\/B> cmdlet is <B>\u2013path<\/B> and it can therefore be left out. The two commands seen here are exactly the same (only one is perhaps a bit easier to read):<\/P><PRE class=\"codeSample\">gc C:\\fso\\Servers.txt\nGet-Content -Path C:\\fso\\Servers.txt\n<\/PRE>\n<P>The <B>%<\/B> character is an alias for the <B>ForEach-Object<\/B> cmdlet. There are four default one-character aliases in Windows PowerShell. The <B>%<\/B>, <B>?<\/B>, <B>h<\/B>, and <B>r<\/B>. You can create your own aliases by using the <B>New-Alias<\/B> cmdlet. If, for example, you think that <B>gc<\/B> is too long, you can replace it with <B>g<\/B> by typing the following command:<\/P><PRE class=\"codeSample\">New-Alias -Name g -Value Get-Content\n<\/PRE>\n<P><B>Gwmi<\/B> is an alias for the <B>Get-WmiObject<\/B> cmdlet. The default parameter is <B>class<\/B>, and it can therefore be left out. However, we cannot leave out the <B>computername<\/B> parameter because the cmdlet gets confused as to what we are trying to tell it. We are supplying only enough of the <B>\u2013computername<\/B> parameter to disambiguate it from the other parameters that also start with the letter <B>c<\/B>, such as <B>\u2013class<\/B>, <B>-computername<\/B>, and <B>-credential<\/B>. The long form of the <B>ForEach-Object<\/B> command and the short form of the same command are seen together here:<\/P><PRE class=\"codeSample\">% { &#8220;Querying $_&#8221; ; gwmi win32_bios -co $_ }\nForEach-Object { &#8220;Querying $_&#8221; ;Get-WmiObject -Class Win32_bios -ComputerName $_ }\n<\/PRE>\n<P>You may think, dude, with the short form being so much shorter, why bother writing the long form? The reason I personally seldom use parameters is that I think it is unfair to people just trying to learn Windows PowerShell to be confronted with a cryptic, unintelligible command. Also, I write lots of scripts. As a best practice, one should never use an alias in a script. This is because aliases are not guaranteed to always be available. This is illustrated here where I delete the <I>gwmi<\/I> alias, and then try to use it again. Dude, it won&#8217;t work!<\/P><PRE class=\"codeSample\">PS C:\\&gt; Remove-Item -Path alias:gwmi -force\nPS C:\\&gt; gwmi win32_bios\nThe term &#8216;gwmi&#8217; is not recognized as a cmdlet, function, operable \nprogram, or script file. Verify the term and try again.\nAt line:1 char:5\n+ gwmi  &lt;&lt;&lt;&lt; win32_bios\n<\/PRE>\n<P>Before you send an e-mail message to scripter@microsoft.com telling us that you accidentally deleted an alias, all you need to do is close Windows PowerShell and open it back up. It will be just fine. The default aliases are automatically recreated each time you open Windows PowerShell. Why, then, do I recommend against using aliases if they are automatically recreated? Because you can remove them in your profile that would be executed each time you open Windows PowerShell, that&#8217;s why.<\/P>\n<P>Oh, but wait, we cheated. Our command does not do the same thing the <B>ReadArgumentsFromText.vbs<\/B> script does. How would we do that? We can do it like this:<\/P><PRE class=\"codeSample\">Get-Content -Path C:\\fso\\Servers.txt | ForEach-Object`\n { (Get-WmiObject -Class Win32_Service -ComputerName $_).count }\n<\/PRE>\n<P>The big thing, was putting parentheses around the <B>Get-WmiObject<\/B> command. We also got rid of the part that printed out the computer names. This is because the <B>ReadArgumentsFromText.vbs<\/B> script does not display the computer name, only the results of the count. When we run our newly modified command, we obtain the results seen here:<\/P><IMG border=\"0\" alt=\"Image of the results of running the newly modified command\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/march\/hey0305\/hsg-3-5-9-3.jpg\" width=\"668\" height=\"163\"> \n<P>&nbsp;<\/P>\n<P>If we were to shorten the command by using aliases, we could reduce the command to about half of one line. The revised command is seen here.<\/P><PRE class=\"codeSample\">gc C:\\fso\\Servers.txt | % {(gwmi win32_service -co $_).count}<\/PRE>\n<P>Speaking of short commands, the <B>\u2013computername<\/B> parameter will accept an array. The <B>Get-Content<\/B> cmdlet produces an array from a text file. This means you could theoretically use the <B>gwmi<\/B> alias for the <B>Get-WmiObject<\/B> cmdlet, specify the WMI class name, and use the <B>\u2013co<\/B> parameter with the <B>gc<\/B> alias for <B>Get-Content<\/B> to read the text file and feed it to the <B>\u2013computername<\/B> parameter. The short version of the command is seen here, followed by the long version:<\/P><PRE class=\"codeSample\">gwmi win32_bios -co(gc C:\\fso\\Servers.txt)\nget-wmiobject -class win32_bios -computername (get-content -path C:\\fso\\Servers.txt)\n<\/PRE>\n<P>The&nbsp;problem with this exact approach, shown in the image below, is that while the data is returned, the computer names are not returned. Therefore, you do not know which BIOS information belongs to which computer.<\/P><IMG border=\"0\" alt=\"Image of the data returned without computer names\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/march\/hey0305\/hsg-3-5-9-4.jpg\" width=\"668\" height=\"535\"> \n<P>&nbsp;<\/P>\n<P>Well, HM, my cup of tea is getting cold, so I need to get back to it. I hope you have seen some tricks that will be beneficial to you when trying to work with remote computers. This concludes WMI Week, and we still did not write a single script. Join us tomorrow for Quick-Hits Friday. Until then, peace.<\/P>\n<P>&nbsp;<\/P>\n<P><B>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/B><\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I want to tell you that I love your articles. I have learned more about tea in the last three months than I ever thought was possible. In fact, if truth be told, I never thought about tea that much. I do like the can of tea from the vending machine, if that counts. Sometimes [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,4,45,6],"class_list":["post-54253","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell","tag-wmi"],"acf":[],"blog_post_summary":"<p>I want to tell you that I love your articles. I have learned more about tea in the last three months than I ever thought was possible. In fact, if truth be told, I never thought about tea that much. I do like the can of tea from the vending machine, if that counts. Sometimes [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54253","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=54253"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54253\/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=54253"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=54253"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=54253"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}