Powershell script to capture OS level properties (CPU, Cores, NIC, Memory, BIOS, OS)

I have a master post which links to a set of powershell scripts all related to this. The Master post which links to all the scripts.

This script is an updated and streamlined version of this original and ugly script

This version actually dumps out to a CSV via the “Export-CSV” command-let. It has some error handling and will check the first WMI call and skip the rest if the first one can’t connect. It has a friendly output to the screen so the user knows which server is currently being queried.

$serverList = "..\SQL Servers.txt"
#$serverList = "test.txt"
[System.Collections.ArrayList]$sysCollection = New-Object System.Collections.ArrayList($null)

foreach ($server in (Get-Content $serverList)) 
{ 
    "Collecting information from $server"
    [System.Collections.Specialized.OrderedDictionary]$si = @{}    # Blank hashtable for each iteration
    $totCores=0

    $si.Server=[string]$server;

    try
    {
        [wmi]$sysInfo = get-wmiobject Win32_ComputerSystem -Namespace "root\CIMV2" -ComputerName $server -ErrorAction Stop
        [wmi]$bios = Get-WmiObject Win32_BIOS -Namespace "root\CIMV2" -computername $server
        [wmi]$os = Get-WmiObject Win32_OperatingSystem -Namespace "root\CIMV2" -Computername $server
        [array]$procs = Get-WmiObject Win32_Processor -Namespace "root\CIMV2" -Computername $server
        [array]$mem = Get-WmiObject Win32_PhysicalMemory -Namespace "root\CIMV2" -ComputerName $server
        [array]$nic = Get-WmiObject Win32_NetworkAdapterConfiguration -Namespace "root\CIMV2" -ComputerName $server | where{$_.IPEnabled -eq "True"}


        $si.Manufacturer=[string]$sysInfo.Manufacturer;
        $si.Model=[string]$sysInfo.Model;
        $si.TotMem=[string]$sysInfo.TotalPhysicalMemory;
        $si.BiosDesc=[string]$bios.Description;
        $si.BiosVer=[string]$bios.SMBIOSBIOSVersion+"."+$bios.SMBIOSMajorVersion+"."+$bios.SMBIOSMinorVersion;
        $si.BiosSerial=[string]$bios.SerialNumber;
        $si.OSName=[string]$os.Name.Substring(0,$os.Name.IndexOf("|") -1);
        $si.Arch=[string]$os.OSArchitecture;
        $si.Processors=[string]@($procs).count;
        $si.Cores=[string]$procs[0].NumberOfCores;
        $iter=0
        while ($iter -lt 12)   #Parse through each stick of memory (arbitrary 12 Memory stick columns)
        {
            if ($mem[$iter] -ne $null) {
                $si."MemBank$iter" = [string]$mem[$iter].Capacity + "," + [string]$mem[$iter].BankLabel 
            } else {
                $si."MemBank$iter" = ""
            }
            $iter++
        }
        $iter=0
        while ($iter -lt 4)    #Parse through each NIC (arbritrary 4 Network Card columns)
        {
            $si."DHCP$iter"=[string]$nic[$iter].DHCPEnabled;
            $si."IPAddress$iter"=[string]$nic[$iter].IPAddress;
            $si."Subnet$iter"=[string]$nic[$iter].IPSubnet;
            $si."Gateway$iter"=[string]$nic[$iter].DefaultIPGateway;
            $si."Mac$iter"=[string]$nic[$iter].MacAddress;
            $iter++
        }
    }
    catch [Exception]
    {
        "Could not contact $server, skipping to next"
        Continue
    }
    finally
    {
        [void]$sysCollection.Add((New-Object PSObject -Property $si))    #Add the dictionary list to the collection
    }
}

$sysCollection | Export-CSV -path ServerInventory.csv -NoTypeInformation    #Output the collection to a CSV file

7 thoughts on “Powershell script to capture OS level properties (CPU, Cores, NIC, Memory, BIOS, OS)

  1. Hi – need your help. your script is basically what I need – but I’m getting errors – and I’m still a beginner when it comes to power-shell
    the error
    _____________________________________________

    Collecting information from xxxxxxxxx
    Cannot convert the “System.Collections.Hashtable” value of type “System.Collect
    ions.Hashtable” to type “System.Collections.Specialized.OrderedDictionary”.
    At C:\…\Bios2.ps1:8 char:58
    + [System.Collections.Specialized.OrderedDictionary]$si <<<< = @{} # Bl
    ank hashtable for each iteration
    + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMet
    adataException
    + FullyQualifiedErrorId : RuntimeException

    Property 'Server' cannot be found on this object; make sure it exists and is settable.
    At C:\…\Bios\Bios2.ps1:11 char:9
    + $si. <<<< Server=[string]$server;
    + CategoryInfo : InvalidOperation: (Server:String) [], RuntimeExc
    eption
    + FullyQualifiedErrorId : PropertyNotFound

    • Do you have a text file named “SQL Servers.txt” that contains a list of servers that you want to connect to and gather the information from?

  2. Hey, awesome script – I have it running and it produces a wealth of useful information … If I wanted the tot memory represented as GIG instead of bytes – what would you modify to accomplish that? I attempted adding /1GB to the end of the .capacity property … but my skills are new an unfinished. What would need to change?

    • Thanks Donny. Off hand, the Win32_PhysicalMemory stores the capacity as a number, it doesn’t have any methods to convert the number. You’re best bet is going to be to do some “math” on the result – within the While loop. Something like $mem[$iter].Capacity / 1024 / 1024 / 1024
      to get to the GB level.

  3. Thanks for the feedback – we played with this some more and was able to get the raw memory converted to the GB representation. I had to explicity declare case as integer within the string to do match against
    the result from mem capacity. The output now represents the size dimm sizes we bought, 4GB, 8GB, 16GB. Again, really nice work.

    [string]([int]($mem[$iter].Capacity/1GB)) + “,” + [string]$mem[$iter].BankLabel

  4. Pingback: Powershell Script: Get Server Inventory - Microsoft Dynamics AX Community

  5. Pingback: Powershell to capture OS / hardware level settings | SQL Blog

Leave a Reply to Donny Cancel reply

Your email address will not be published.

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.