Get-PCInfo – Query System Information on Remote Computers with #PowerShell

Mike has done a great job with his blog on how to retrieve Basic Operating System Information with PowerShell. Highly recommend to read his blog HERE before proceeding further.

This post is to compliment his work and go overboard with additional details that may be required by people who are relatively new to PowerShell. Most of the heavy lifting is done via CIM Session for optimum performance for querying remote computers.

While most of my script is borrowed from his, however I had the need to run-in a few customizations as detailed below.

I used read-host to get a Computer Name as feed:

$computer = Read-Host "Please enter a computer name" 

#Test network connection before making connection

If ($computer -ne $Env:Computername) { 

   If (!(Test-Connection -ComputerName $computer -count 1 -quiet)) { 

       Write-Warning "$computer is not accessible, please try a different computer or verify it is connected and powered on." 

       Break 

        } 

    }

Still using the standard CIM Session method to query Properties from well-known classes such as Win32_OperatingSystem, Win32_ComputerSystem, Win32_ComputerSystemProduct and Win32_BIOS

For authentication, you may also use the Credential Parameter for Multi Domain Environment

$CimSession = New-CimSession -ComputerName $computer -Credential Contoso\AdminUser

Sample Variables are as follows

$OSInfo = Get-CimInstance -CimSession $CimSession -ClassName Win32_OperatingSystem -Property * | Select-Object Caption, BuildNumber, OSArchitecture, CSName, Version

$PCInfo = Get-CimInstance -CimSession $CimSession -ClassName Win32_ComputerSystem -Property * | Select-Object DNSHostName, Domain, Manufacturer, Model, UserName

$CSProductInfo = Get-CimInstance -CimSession $CimSession -ClassName Win32_ComputerSystemProduct -Property * | Select-Object Version, IdentifyingNumber, UUID

$BIOSInfo = Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS -Property * | Select-Object SerialNumber, SMBIOSBIOSVersion

I have also utilized a new CIM Class CIM_DataFile with the Filter Parameter set to query the version of an executable file by name CustomExecutableClient.exe (Change as per your requirements) located at C:\Program Files (x86)\Corporate\ABC\ folder path (Change as per your requirements)

$PCPVersion = Get-CimInstance -CimSession $CimSession -ClassName CIM_DataFile -Filter "Name = 'C:\\Program Files (x86)\\Corporate\\ABC\\CustomExecutableClient.exe'"
  • Note – Mind the double back slashes for CIM and WMI calls. Single Slashes to Folder path will fail.

We have used the StdRegProv CIM Class to Query the registry keys and entries with values.

For (default) registry entry for a String and its value we would use the Method GetStringvalue. Property value for (default) is fetched by sValue

$AdobeVer = Invoke-CimMethod -CimSession $CimSession -Namespace root\cimv2 -ClassName StdRegProv -MethodName GetSTRINGvalue -Arguments @{
                                hDefKey=[uint32]2147483650; sSubKeyName='Software\Wow6432Node\Adobe\Shockwave 12\currentupdateversion'}

For DWORD registry entry and its value we would use the Method GetDWORDvalue. Property value for DWORD is fetched by uValue

$AVDatVersion = Invoke-CimMethod -CimSession $CimSession -Namespace root\cimv2 -ClassName StdRegProv -MethodName GetDWORDvalue -Arguments @{

                    hDefKey=[uint32]2147483650; sSubKeyName='Software\Wow6432Node\McAfee\AVEngine'; sValueName='AVDatVersion'}

For STRING registry entry and its value we would use the Method GetStringvalue. Property value for STRING is fetched by sValue

$AVDatDate = Invoke-CimMethod -CimSession $CimSession -Namespace root\cimv2 -ClassName StdRegProv -MethodName GetSTRINGvalue -Arguments @{

                    hDefKey=[uint32]2147483650; sSubKeyName='Software\Wow6432Node\McAfee\AVEngine'; sValueName='AVDatDate'}

Hash Table is pretty straight forward

             [pscustomobject]@{

            ComputerName = $OSInfo.CSName

            OSDReleaseVersion = $OSDRelease.sValue

            Manufacturer = $PCInfo.Manufacturer

            Model = $PCInfo.Model

            UserName = $PCInfo.UserName

            HWVersion = $CSProductInfo.Version

            IndentifyingNumber = $CSProductInfo.IdentifyingNumber

            UUID = $CSProductInfo.UUID

            SerialNumber = $BIOSInfo.SerialNumber

            SMBIOSVersion = $BIOSInfo.SMBIOSBIOSVersion

            OperatingSystem = $OSInfo.Caption

            OSVersion = $OSInfo.Version

            BuildNumber = $OSInfo.BuildNumber

            OSArchitecture = $OSInfo.OSArchitecture

            PCPVersion = $PCPVersion.Version

            AVDatVersion = $AVDatVersion.uValue

            AVDatDate = $AVDatDate.sValue

            PowerShellVersion = $PSVersion.sValue

        }

Property and Methods can be referred as below

CIM-RegClass

Here is the full script

function Get-SystemInfo {
<#
.SYNOPSIS
Retrieves key system version and model information from multiple computers.
.DESCRIPTION
Get-SystemInfo uses CIM Sessions (CIM) to retrieve information from one or more computers.
Specify computers by name or by IP address or separated by COMMA or use Get-Content to a txt file.
.PARAMETER ComputerName
One or more computer names or IP addresses.
.PARAMETER LogErrors
Specify this switch to create a text log file of computers that could not be queried.
.PARAMETER ErrorLog
When used with -LogErrors, specifies the file path and name to which failed computer names will be written. Defaults to C:\Retry.txt.
.EXAMPLE
Get-Content names.txt | Get-SystemInfo
.EXAMPLE
Get-SystemInfo -ComputerName SERVER1,SERVER2
#>

[CmdletBinding()]
param(
        [Parameter(Mandatory=$True,ValueFromPipeline=$True,HelpMessage="Computer name or IP address")]
        [Alias('hostname')]
        [string[]]$ComputerName,
        [string]$ErrorLog = 'c:\Retry.txt',
        [switch]$LogErrors,
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential = [System.Management.Automation.PSCredential]::Empty
        
)
BEGIN {
        Write-Verbose "Error log will be $ErrorLog"
}
PROCESS {
        Write-Verbose "Beginning PROCESS block"
        foreach ($computer in $computername) {
            Write-Verbose "Querying $computer"
            Try {
                $everything_ok = $true
                #$os = Get-WmiObject -class Win32_OperatingSystem -computerName $computer -erroraction Stop
                $Cimsession = New-CimSession -computerName $computer -Credential $Credential -erroraction Stop
                } Catch {
                $everything_ok = $false
                Write-Warning "$computer failed"
                if ($LogErrors) {
                $computer | Out-File $ErrorLog -Append
                Write-Warning "Logged to $ErrorLog"
                }
                }
                if ($everything_ok) {
                # Here are the CIM Queuries to various classes as per the information you wish to extract
                $OSInfo = Get-CimInstance -CimSession $CimSession -ClassName Win32_OperatingSystem -Property * | Select-Object Caption, BuildNumber, OSArchitecture, CSName, Version
                $PCInfo = Get-CimInstance -CimSession $CimSession -ClassName Win32_ComputerSystem -Property * | Select-Object DNSHostName, Domain, Manufacturer, Model, UserName
                $CSProductInfo = Get-CimInstance -CimSession $CimSession -ClassName Win32_ComputerSystemProduct -Property * | Select-Object Version, IdentifyingNumber, UUID
                $BIOSInfo = Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS -Property * | Select-Object SerialNumber, SMBIOSBIOSVersion
                # Here is CIM Query to fetch File version
                $PCPVersion = Get-CimInstance -CimSession $CimSession -ClassName CIM_DataFile -Filter "Name = 'C:\\Program Files (x86)\\Corporate\\PCP\\Daimler.Pcp.Client.Service.exe'"
                # This one fetches the Users and Groups that are members of the Local Administrators group
                $GetGroupUser = Get-CimInstance -CimSession $CimSession -Class Win32_GroupUser -Filter "GroupComponent=""Win32_Group.Domain='$($OSInfo.CSName)',Name='Administrators'"""
                $GetGroupUserPartComponent = $GetGroupUser.PartComponent
                # Here is CIM Query to fetches all local groups that have the word *Remote* in them
                $GetGroup = Get-CimInstance -CimSession $CimSession -ClassName Win32_Group | where Caption -Like *Remote*
                # These are CIM Queries for fetching Registry Keys, Properties and their Values
                # This one fetches the property value of Registry entry as STRING
                $ProvisioningMode = Invoke-CimMethod -CimSession $CimSession -Namespace root\cimv2 -ClassName StdRegProv -MethodName GetSTRINGvalue -Arguments @{
                                hDefKey=[uint32]2147483650; sSubKeyName='SOFTWARE\Microsoft\CCM\CCMExec'; sValueName='ProvisioningMode'}
                # This one fetches the property value of Registry entry as DWORD
                $AVDatVersion = Invoke-CimMethod -CimSession $CimSession -Namespace root\cimv2 -ClassName StdRegProv -MethodName GetDWORDvalue -Arguments @{
                                hDefKey=[uint32]2147483650; sSubKeyName='Software\Wow6432Node\McAfee\AVEngine'; sValueName='AVDatVersion'}
                $AVDatDate = Invoke-CimMethod -CimSession $CimSession -Namespace root\cimv2 -ClassName StdRegProv -MethodName GetSTRINGvalue -Arguments @{
                                hDefKey=[uint32]2147483650; sSubKeyName='Software\Wow6432Node\McAfee\AVEngine'; sValueName='AVDatDate'}
                $PSVersion = Invoke-CimMethod -CimSession $CimSession -Namespace root\cimv2 -ClassName StdRegProv -MethodName GetSTRINGvalue -Arguments @{
                                hDefKey=[uint32]2147483650; sSubKeyName='SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine'; sValueName='PowerShellVersion'}
                $OSDRelease = Invoke-CimMethod -CimSession $CimSession -Namespace root\cimv2 -ClassName StdRegProv -MethodName GetSTRINGvalue -Arguments @{
                                hDefKey=[uint32]2147483650; sSubKeyName='SYSTEM\Corporate\MachineData'; sValueName='DeploymentConfiguration'}
                # For (default) registry entry for a String and its value we would use the Method GetStringvalue. Property value for (default) is fetched by sValue
                $AdobeVer = Invoke-CimMethod -CimSession $CimSession -Namespace root\cimv2 -ClassName StdRegProv -MethodName GetSTRINGvalue -Arguments @{
                                hDefKey=[uint32]2147483650; sSubKeyName='Software\Wow6432Node\Adobe\Shockwave 12\currentupdateversion'}
                $props = @{
                            ComputerName = $OSInfo.CSName;
                            OSDReleaseVersion = $OSDRelease.sValue;
                            ProvisioningMode = $ProvisioningMode.sValue
                            AdobeVer = $AdobeVer.sValue
                            Manufacturer = $PCInfo.Manufacturer;
                            Model = $PCInfo.Model;
                            UserName = $PCInfo.UserName;
                            HWVersion = $CSProductInfo.Version;
                            IndentifyingNumber = $CSProductInfo.IdentifyingNumber;
                            UUID = $CSProductInfo.UUID;
                            SerialNumber = $BIOSInfo.SerialNumber;
                            SMBIOSVersion = $BIOSInfo.SMBIOSBIOSVersion;
                            OperatingSystem = $OSInfo.Caption;
                            OSVersion = $OSInfo.Version;
                            BuildNumber = $OSInfo.BuildNumber;
                            OSArchitecture = $OSInfo.OSArchitecture;
                            PCPVersion = $PCPVersion.Version;
                            AVDatVersion = $AVDatVersion.uValue;
                            AVDatDate = $AVDatDate.sValue;
                            PowerShellVersion = $PSVersion.sValue;
                            AdminMemberName = $GetGroupUserPartComponent.Name;
                            LocalGroups = $GetGroup.Caption;
                            }
                Write-Verbose "CIM queries complete"
                $obj = New-Object -TypeName PSObject -Property $props
                Write-Output $obj
}
}
}
END {Remove-CimSession $Cimsession }
}
Get-SystemInfo –computername <ComputerName_FQDN_IP> -Credential Username

#Get-SystemInfo –computername localhost -Credential Username -LogErrors

 

 

Thank You.

Feel free to adapt as per your requirements. As for the pipeline and other enhancements, you may adapt the sophistication from Mike’s blog

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s