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 

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Digg
  • Furl
  • Reddit
  • Technorati
  • YahooMyWeb

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

 

Leave a Comment

« Windows PowerShell Programming - for the absolute beginner | Home | Windows PowerShell : The Definitive Guide »