3 Easy Steps to Get Information from Multiple Remote Computers…

By Jesse Hamrick • September 1st, 2007

PowerShell Script - Multiple ComputersAs I perused the "Computer Hardware" section of the PowerShell Script Repository, I noticed that every PowerShell script uses the $strComputer = "." variable. Meaning the script only enumerates information on the "Local Computer." Not very practical in the "real-world," I don't know too many of you running scripts locally on each computer in your environment (excluding log on scripts of course…). This article expands on the Microsoft provided examples by exhibiting how to remotely connect to multiple computers and enumerate data, even if you have thousands of computers to inventory…

The method I employ, create an array from entries listed in a text file and run the script against each entry. Very simple to accomplish.

Here is the example we will be working with. This script, from the Microsoft PowerShell script repository, enumerates the BIOS information from the local machine. Below this example are the steps to gather BIOS information from multiple machines.

 

$strComputer = "."

$colItems = get-wmiobject -class "Win32_BIOS" -namespace "root\CIMV2" `
-computername $strComputer

foreach ($objItem in $colItems) {
      write-host "BIOS Characteristics: " $objItem.BiosCharacteristics
      write-host "BIOS Version: " $objItem.BIOSVersion
      write-host "Build Number: " $objItem.BuildNumber
      write-host "Caption: " $objItem.Caption
      write-host "Code Set: " $objItem.CodeSet
      write-host "Current Language: " $objItem.CurrentLanguage
      write-host "Description: " $objItem.Description
      write-host "Identification Code: " $objItem.IdentificationCode
      write-host "Installable Languages: " $objItem.InstallableLanguages
      write-host "Installation Date: " $objItem.InstallDate
      write-host "Language Edition: " $objItem.LanguageEdition
      write-host "List Of Languages: " $objItem.ListOfLanguages
      write-host "Manufacturer: " $objItem.Manufacturer
      write-host "Name: " $objItem.Name
      write-host "Other Target Operating System: " $objItem.OtherTargetOS
      write-host "Primary BIOS: " $objItem.PrimaryBIOS
      write-host "Release Date: " $objItem.ReleaseDate
      write-host "Serial Number: " $objItem.SerialNumber
      write-host "SMBIOS BIOS Version: " $objItem.SMBIOSBIOSVersion
      write-host "SMBIOS Major Version: " $objItem.SMBIOSMajorVersion
      write-host "SMBIOS Minor Version: " $objItem.SMBIOSMinorVersion
      write-host "SMBIOS Present: " $objItem.SMBIOSPresent
      write-host "Software Element ID: " $objItem.SoftwareElementID
      write-host "Software Element State: " $objItem.SoftwareElementState
      write-host "Status: " $objItem.Status
      write-host "Target Operating System: " $objItem.TargetOperatingSystem
      write-host "Version: " $objItem.Version
      write-host
}

Step 1. Create a text file C:\MyScripts\Computers.txt and import or enter each computer name on a separate line. For Example:
Computer01
Computer02
Computer03
Etc…

Step 2. Change the PowerShell script code from strComputer = "." to strComputer = Get-Content -Path "C:\MyScripts\Computers.txt"

$strComputer = Get-Content -Path "C:\MyScripts\Computers.txt"

$colItems = get-wmiobject -class "Win32_BIOS" -namespace "root\CIMV2" `
-computername $strComputer

foreach ($objItem in $colItems) {
      write-host "BIOS Characteristics: " $objItem.BiosCharacteristics
      write-host "BIOS Version: " $objItem.BIOSVersion
      write-host "Build Number: " $objItem.BuildNumber
      write-host "Caption: " $objItem.Caption
      write-host "Code Set: " $objItem.CodeSet
      write-host "Current Language: " $objItem.CurrentLanguage
      write-host "Description: " $objItem.Description
      write-host "Identification Code: " $objItem.IdentificationCode
      write-host "Installable Languages: " $objItem.InstallableLanguages
      write-host "Installation Date: " $objItem.InstallDate
      write-host "Language Edition: " $objItem.LanguageEdition
      write-host "List Of Languages: " $objItem.ListOfLanguages
      write-host "Manufacturer: " $objItem.Manufacturer
      write-host "Name: " $objItem.Name
      write-host "Other Target Operating System: " $objItem.OtherTargetOS
      write-host "Primary BIOS: " $objItem.PrimaryBIOS
      write-host "Release Date: " $objItem.ReleaseDate
      write-host "Serial Number: " $objItem.SerialNumber
      write-host "SMBIOS BIOS Version: " $objItem.SMBIOSBIOSVersion
      write-host "SMBIOS Major Version: " $objItem.SMBIOSMajorVersion
      write-host "SMBIOS Minor Version: " $objItem.SMBIOSMinorVersion
      write-host "SMBIOS Present: " $objItem.SMBIOSPresent
      write-host "Software Element ID: " $objItem.SoftwareElementID
      write-host "Software Element State: " $objItem.SoftwareElementState
      write-host "Status: " $objItem.Status
      write-host "Target Operating System: " $objItem.TargetOperatingSystem
      write-host "Version: " $objItem.Version
      write-host
}

 

The script works because the "Get-Content" cmdlet builds an array from the entries in the text file. There still is a problem, no property exists for the computer name. If you run this script against 500 machines how would you correlate which computer sent which BIOS information? We need to tweak the script to provide us with the name of the computer sending the information.

Step 3. Flow control using "Foreach-Object" cmdlet. Essentially, I'm controlling the flow of the script by nesting script blocks. Here's what the code, below, is doing:

  • Uses "$arrComputers" variable to store the array created by the "Get-Content" cmdlet.
  • Use "Foreach-Object" cmdlets to control the flow of the script (the script uses the "foreach" alias). It connects to a computer's wmi "Win32_bios" class and enumerates the BIOS information, before moving to the next computer in the array.
  • We can then use the "$strComputer" variable to output the computer name in the results, Write-Host "ComputerName: " $strComputer

$arrComputers = get-Content -Path "C:\MyScripts\Computers.txt"

foreach ($strComputer in $arrComputers)
{
    $colItems = get-wmiobject -class "Win32_BIOS" -namespace "root\CIMV2" `
    -computername $strComputer

   foreach ($objItem in $colItems)
   {

     Write-host "Computer Name: " $strComputer

      write-host "BIOS Characteristics: " $objItem.BiosCharacteristics
      write-host "BIOS Version: " $objItem.BIOSVersion
      write-host "Build Number: " $objItem.BuildNumber
      write-host "Caption: " $objItem.Caption
      write-host "Code Set: " $objItem.CodeSet
      write-host "Current Language: " $objItem.CurrentLanguage
      write-host "Description: " $objItem.Description
      write-host "Identification Code: " $objItem.IdentificationCode
      write-host "Installable Languages: " $objItem.InstallableLanguages
      write-host "Installation Date: " $objItem.InstallDate
      write-host "Language Edition: " $objItem.LanguageEdition
      write-host "List Of Languages: " $objItem.ListOfLanguages
      write-host "Manufacturer: " $objItem.Manufacturer
      write-host "Name: " $objItem.Name
      write-host "Other Target Operating System: " $objItem.OtherTargetOS
      write-host "Primary BIOS: " $objItem.PrimaryBIOS
      write-host "Release Date: " $objItem.ReleaseDate
      write-host "Serial Number: " $objItem.SerialNumber
      write-host "SMBIOS BIOS Version: " $objItem.SMBIOSBIOSVersion
      write-host "SMBIOS Major Version: " $objItem.SMBIOSMajorVersion
      write-host "SMBIOS Minor Version: " $objItem.SMBIOSMinorVersion
      write-host "SMBIOS Present: " $objItem.SMBIOSPresent
      write-host "Software Element ID: " $objItem.SoftwareElementID
      write-host "Software Element State: " $objItem.SoftwareElementState
      write-host "Status: " $objItem.Status
      write-host "Target Operating System: " $objItem.TargetOperatingSystem
      write-host "Version: " $objItem.Version
      write-host
   }
}

 

Now there is a correlation between the computer name and the results. In "blue" is the nested script block. In "red" is the $strComputer variable that outputs the computer name in the results.

I supplied this example so that you can enumerate information from multiple remote computers. Any PowerShell script, on the Microsoft site, that uses the $strComputer = "." variable can be modified using the example above.

Happy scripting… 

Email This Post To A Friend Email This Post To A Friend 

Comments

By Daniel Munoz on November 6th, 2007 at 1:57 pm

Outstanding! Your explanation is excellent and it will help me out so much. I’ve already created some scripts that I use constantly. Thank you.

The Write-host “Computer Name: ” $strComputer writes all the values in the array every time it loops.

By NetGuyDave on August 13th, 2008 at 8:19 am

I agree with Daniel – ditto. But…how do I compile a list of computers? We have 700 computers on 6 different subnets with several being managed by 3rd party companies – who knows what machine names they build and tear down on a weekly basis. Is there a way the script can do a ping “if statement” on an entire IP range then query for information that responds with a successfull ping? Or..any other ideas to build a computer name txt file are more than welcome. Thanks, Dave

Check out PowerShell ping sweep from ScriptingAnswers.com – http://www.scriptinganswers.com/vault/Misc%20PowerShell/

-Jesse

Jesse, I don’t know how you find this stuff but it is very much appreciated! Thank You, Dave

yeah this is a pretty good way of going about it. However, I wonder why you did not just use the __server for getting the computer name. It is in every WMI object I have seen thus far and makes it really easy to code in. Guess it does not make a real difference either way.

I am totally new at this. Try the code and getting this error:
The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
can you please help me?

thanks.

I got the same error regarding the RPC server not being available. Its because the Windows firewall is blocking the remote connection. I’ve done a bunch of search and made sure my group policy was set to allow remote administration and file and print sharing in the firewall, but it still doesn’t work. I think it has something to do the DCOM using dynamic port mappings, but it just doesn’t seem to work with WinXP clients. It works fine with Vista. Any tips would be appreciated.

Needed something quick and found this.

thanks a bunch.

I wrote a powershell script to query remote hosts via WMI plus do some formatting to make the data easier to read.

It will return data from the following WMI classes:
Win32_OperatingSystem
Win32_ComputerSystem
Win32_NetworkAdapter plus associated Win32_NetworkAdapterConfiguration
Win32_LogicalDisk
Win32_PhysicalMemory
Win32_Processor
Win32_PageFileSetting

Check it out and download from here:

http://poshtips.com/2011/03/25/gethostinfo-remote-host-query-script-using-wmi/

I’ve prepared a script to query remote hosts and do some formatting for easier readability. Check it out here:

http://poshtips.com/2011/03/25/gethostinfo-remote-host-query-script-using-wmi/

i’m new at scripting and this works great
except for some of my workstations where i get this error:

Get-WmiObject : Access is denied. (Exception from HRESULT: 0×80070005 (E_ACCESSDENIED))
At C:\Users\maarten\AppData\Local\Temp\777057e6-4d0c-4c5f-900a-bd6c197ead2b.ps1:5 char:30
+ $colItems = get-wmiobject <<<< -class "Win32_BIOS" -namespace "root\CIMV2" `
+ CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

could this be my firewall?

I am new to scripting and not sure what is the mistake.. I am not able to get the Powershell result to output file…

$arrComputers = (get-Content D:\Server.txt)
$Path = “D:\Serial.txt”

foreach ($strComputer in $arrComputers)
{
$colItems = get-wmiobject -class “Win32_BIOS” -namespace “root\CIMV2″ `
-computername $strComputer

foreach ($objItem in $colItems)
{
Write-Host “Computer Name: ” $strComputer
write-Host “Manufacturer: ” $objItem.Manufacturer
write-Host “Serial Number: ” $objItem.SerialNumber
write-host “Version: ” $objItem.Version
write-Host
}
}
Out-File $Path

Kindly help me!!

By Vijay Dogra on February 5th, 2013 at 3:12 am

$arrComputers = (get-Content D:\Server.txt)
$Path = “D:\Serial.csv”
$data = “” | Select-Object Computername,Manufacturer,SerialNumber,Version
foreach ($strComputer in $arrComputers)
{
$colItems = get-wmiobject -class “Win32_BIOS” -namespace “root\CIMV2″ `
-computername $strComputer
foreach ($objItem in $colItems)
{
$data.Computername += $strComputer
$data.Manufacturer += $objItem.Manufacturer
$data.SerialNumber += $objItem.SerialNumber
$data.Version += $objItem.Version
}
}

$data | Export-Csv -Path $Path -NoTypeInformation

Hi, i am not getting the all the details. Few details are missing. Could you please help me on this.
PS D:\Script> .\Computer.ps1
Computer Name: KLT-IN-AJoshi
BIOS Characteristics: 7 11 12 14 15 16 17 19 23 24 25 26 27 28 29 30 32 33 36 37 40 42 50 57 58 64 65 66 67 68 69 70 71
72 73 74 75 76 77 78 79
BIOS Version: DELL – 6222004
Build Number:
Caption: Default System BIOS
Code Set:
Current Language: en|US|iso8859-1
Description: Default System BIOS
Identification Code:
Installable Languages: 1
Installation Date:
Language Edition:
List Of Languages: en|US|iso8859-1
Manufacturer: Dell Inc.
Name: Default System BIOS
Other Target Operating System:
Primary BIOS: True
Release Date: 20120509000000.000000+000
Serial Number: 8BZY7BS
SMBIOS BIOS Version: A12
SMBIOS Major Version: 2
SMBIOS Minor Version: 6
SMBIOS Present: True
Software Element ID: Default System BIOS
Software Element State: 3
Status: OK
Target Operating System: 0
Version: DELL – 6222004
OS Name: Name
Processor:

 

Leave a Comment

« | Home | »