Last active
February 2, 2022 07:38
-
-
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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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