Skip to content

Instantly share code, notes, and snippets.

@SP3269
Last active February 2, 2022 07:38
Show Gist options
  • Select an option

  • Save SP3269/13ec35fee892af3af9c6c7520a64cebc to your computer and use it in GitHub Desktop.

Select an option

Save SP3269/13ec35fee892af3af9c6c7520a64cebc to your computer and use it in GitHub Desktop.
PowerShell functon that collects information about a Windows system (due to Windows-specific CIM classes), including process I/O and network bandwidth data. Sample data collection from Windows systems. Includes top I/O consumer processes. Run in parallel for performance (tested ~5K systems in ~20 minutes).
# This is a simple Powershell script that probes a system for management interface, negotiates protocol and queries management data
# Some of it is pretty standard, such as make/model/RAM/OS
# The interesting bit, quite useful in production, is the top processes by read and write I/O activity
# Run in parallel against multiple systems, and you have dataset describing your environment!
function Get-ComputerData {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline=$true)] $ComputerName="localhost"
)
try { $wsman = Test-WSMan $ComputerName -ErrorAction Stop } catch { Write-Verbose "Error testing WSMan on $system"; return $null }
# Creating CIM Session
$wsmanstackversion = [single]$wsman.ProductVersion.split(' ')[5] # Splits ProductVersion string i.e. "OS: 0.0.0 SP: 0.0 Stack: 2.0" and converts to number for comparing
if ( $wsmanstackversion -ge 3 ) { $cimprotocol = "WSMan" } else { $cimprotocol = "DCOM" }
$cimsessionoption = New-CimSessionOption -Protocol $cimprotocol
try { $cimsession = New-CimSession -ComputerName $ComputerName -OperationTimeoutSec 20 -SessionOption $cimsessionoption -ErrorAction Stop } catch { Write-Verbose "Error establishing CIM session to $system"; return $null }
# Now that CIM session is established, we can read data from it
try {
# System data - Make/model/RAM
$compsystem = Get-CimInstance Win32_ComputerSystem -CimSession $cimsession -OperationTimeoutSec 30 -ErrorAction Stop
# OS data - OS, install date
$os = Get-CimInstance Win32_OperatingSystem -CimSession $cimsession -OperationTimeoutSec 30 -ErrorAction Stop
# QFE Updates Information
$updates = Get-CimInstance Win32_QuickFixEngineering -CimSession $cimsession -OperationTimeoutSec 30 -ErrorAction Stop
$datedupdates = $updates | ? { $_.InstalledOn }
if ( $datedupdates ) { $lastknownupdate = ($datedupdates | sort InstalledOn -Descending)[0].InstalledOn } else { $lastknownupdate = $null }
# Process performance information
$procperf = Get-CimInstance Win32_PerfRawData_PerfProc_Process -CimSession $cimsession -OperationTimeoutSec 30 -ErrorAction Stop
$procperfr = $procperf | select Name,IOReadOperationsPersec,Timestamp_PerfTime,Frequency_PerfTime | sort IOReadOperationsPersec -Descending | select -First 2 # Selecting total and the top reader
$procperfw = $procperf | select Name,IOWriteOperationsPersec,Timestamp_PerfTime,Frequency_PerfTime | sort IOWriteOperationsPersec -Descending | select -First 2 # Selecting total and the top writer
$procperfmem = $procperf | select Name,WorkingSetPeak | sort WorkingSetPeak -Descending | select -First 2 # Total and top memory utilising process
$netiostat = Get-CimInstance Win32_PerfRawData_Tcpip_Networkinterface -CimSession $cimsession -OperationTimeoutSec 30 -ErrorAction Stop
$bwidth = ($netiostat | select Name, @{N="bwidth"; E={$_.bytestotalpersec/$_.timestamp_perftime*$_.frequency_perftime}} | sort bwidth -Descending)[0].bwidth
}
catch { Write-Verbose "Error getting data from CIM session to $system"; return $null }
# And dispose of the CIM session
Remove-CimSession $cimsession
$computerdata = New-Object PSObject -Property @{
Name = $ComputerName
WSManVersion = $wsman.ProductVersion
NumberOfUpdates = $updates.count
LastUpdateOn = $lastknownupdate
Make = $compsystem.Manufacturer
Model = $compsystem.Model
RAM = $compsystem.TotalPhysicalMemory
Description = $os.Description
OSInstallDate = $os.InstallDate
LastBootUpTime = $os.LastBootUpTime
AvgReadsPerSec = $procperfr[0].IOReadOperationsPersec/$procperf[0].Timestamp_PerfTime*10000000
TopReaderProcess = $procperfr[1].Name
TopReaderProcessAvgReadsPerSec = $procperfr[1].IOReadOperationsPersec/$procperfr[1].Timestamp_PerfTime*$procperfr[1].Frequency_PerfTime
TopWriterProcess = $procperfw[1].Name
TopWriterProcessAvgWritesPerSec = $procperfw[1].IOWriteOperationsPersec/$procperfw[1].Timestamp_PerfTime*$procperfw[1].Frequency_PerfTime
WorkingSetPeak = $procperfmem[0].WorkingSetPeak
TopMemoryProcess = $procperfmem[1].Name
Bandwidth = $bwidth
}
return $computerdata
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment