Public/system/Get-SystemSummary.ps1
|
#Requires -Version 5.1 function Get-SystemSummary { <# .SYNOPSIS Gather comprehensive system information from Windows machines .DESCRIPTION Queries six WMI/CIM classes to build a detailed system summary for local or remote Windows machines. Supports pipeline input, explicit credentials for remote hosts, and returns a structured PSCustomObject per machine. CIM session management and cleanup are handled automatically. .PARAMETER ComputerName One or more computer names or IP addresses to query. Defaults to the local machine. Accepts pipeline input by value and by property name. .PARAMETER Credential Optional PSCredential used to authenticate against remote machines. Ignored for local queries. Obtain via Get-Credential or SecretManagement. .EXAMPLE Get-SystemSummary Returns a full system summary for the local machine. .EXAMPLE Get-SystemSummary -ComputerName 'SRV01', 'SRV02' -Credential (Get-Credential) Returns system summaries for two remote servers using explicit credentials. .EXAMPLE 'WEB01', 'WEB02' | Get-SystemSummary -Verbose Queries two machines via pipeline input with verbose logging. .NOTES Author: Franck SALLET Version: 1.0.0 Last Modified: 2026-03-15 Requires: PowerShell 5.1+, CIM/WMI access on target machines Permissions: Local admin or equivalent WMI read permissions on remote targets #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [string[]]$ComputerName = @($env:COMPUTERNAME), [Parameter(Mandatory = $false)] [PSCredential]$Credential ) begin { Write-Verbose "[$($MyInvocation.MyCommand)] Starting" $localNames = @($env:COMPUTERNAME, 'localhost', '.') $hasCredential = $PSBoundParameters.ContainsKey('Credential') } process { foreach ($machine in $ComputerName) { $cimSession = $null try { $isLocal = $localNames -contains $machine # Build common CIM params for this machine (splat for all 6 classes) $cimParams = @{ ErrorAction = 'Stop' } if (-not $isLocal) { if ($hasCredential) { $cimSession = New-CimSession -ComputerName $machine -Credential $Credential -ErrorAction Stop $cimParams['CimSession'] = $cimSession } else { $cimParams['ComputerName'] = $machine } } # Query all 6 CIM classes $system = Get-CimInstance -ClassName 'Win32_ComputerSystem' @cimParams $os = Get-CimInstance -ClassName 'Win32_OperatingSystem' @cimParams $bios = Get-CimInstance -ClassName 'Win32_BIOS' @cimParams $processor = Get-CimInstance -ClassName 'Win32_Processor' @cimParams | Select-Object -First 1 $disks = Get-CimInstance -ClassName 'Win32_LogicalDisk' @cimParams | Where-Object -FilterScript { $_.DriveType -eq 3 } $networkAdapters = Get-CimInstance -ClassName 'Win32_NetworkAdapterConfiguration' @cimParams | Where-Object -FilterScript { $null -ne $_.DefaultIPGateway } # Calculate uptime $uptime = (Get-Date) - $os.LastBootUpTime # Build disk summary strings $diskSummary = ($disks | ForEach-Object -Process { '[{0}] {1} ({2}) {3:N2}/{4:N2} GB ({5:N1}% Free)' -f $_.FileSystem, $_.DeviceID, $_.VolumeName, ($_.FreeSpace / 1GB), ($_.Size / 1GB), (($_.FreeSpace / $_.Size) * 100) }) -join ' | ' # Extract IPv4 addresses only $ipv4Addresses = ($networkAdapters.IPAddress | Where-Object -FilterScript { $_ -match '^\d+\.\d+\.\d+\.\d+$' }) -join ', ' $gatewayList = ($networkAdapters.DefaultIPGateway) -join ', ' $dnsList = ($networkAdapters.DNSServerSearchOrder) -join ', ' # Determine PS version string $psVersionString = if ($isLocal) { $PSVersionTable.PSVersion.ToString() } else { 'N/A (remote)' } [PSCustomObject]@{ PSTypeName = 'PSWinOps.SystemSummary' ComputerName = $machine Domain = $system.Domain OSName = $os.Caption OSVersion = $os.Version OSArchitecture = $os.OSArchitecture InstallDate = $os.InstallDate LastBootTime = $os.LastBootUpTime UptimeDays = [decimal][math]::Round($uptime.TotalDays, 2) UptimeDisplay = '{0} days, {1} hours, {2} minutes' -f $uptime.Days, $uptime.Hours, $uptime.Minutes Manufacturer = $system.Manufacturer Model = $system.Model SerialNumber = $bios.SerialNumber BIOSVersion = $bios.SMBIOSBIOSVersion Processor = $processor.Name.Trim() TotalCores = [int]$processor.NumberOfCores TotalLogicalProcessors = [int]$processor.NumberOfLogicalProcessors TotalRAMGB = [decimal][math]::Round($system.TotalPhysicalMemory / 1GB, 2) FreeRAMGB = [decimal][math]::Round($os.FreePhysicalMemory / 1MB, 2) RAMUsagePercent = [decimal][math]::Round((1 - ($os.FreePhysicalMemory / $os.TotalVisibleMemorySize)) * 100, 1) Disks = $diskSummary IPAddresses = $ipv4Addresses DefaultGateway = $gatewayList DNSServers = $dnsList PSVersion = $psVersionString Timestamp = Get-Date -Format 'o' } } catch { Write-Error "[$($MyInvocation.MyCommand)] Failed on '${machine}': $_" } finally { if ($null -ne $cimSession) { Remove-CimSession -CimSession $cimSession -ErrorAction SilentlyContinue } } } } end { Write-Verbose "[$($MyInvocation.MyCommand)] Completed" } } |