Private/Kinds/System.ps1
|
# The System Kind: what the machine is. # # Two Checks here are about age rather than a reading, so the Gatherer records when it # looked. The Judge computes the age from that rather than from the clock, which keeps it # pure and lets a fixture pin an age exactly. function Get-SystemData { [CmdletBinding()] [OutputType([psobject])] param([hashtable]$Parameters = @{}) $computer = Get-CimInstance Win32_ComputerSystem -ErrorAction SilentlyContinue $os = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue $bios = Get-CimInstance Win32_BIOS -ErrorAction SilentlyContinue $cpu = @(Get-CimInstance Win32_Processor -ErrorAction SilentlyContinue)[0] $current = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -ErrorAction SilentlyContinue $power = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power' -ErrorAction SilentlyContinue $modules = @(Get-CimInstance Win32_PhysicalMemory -ErrorAction SilentlyContinue | ForEach-Object { [pscustomobject]@{ CapacityBytes = $_.Capacity; ConfiguredClockSpeed = $_.ConfiguredClockSpeed } }) [pscustomobject]@{ PSTypeName = 'Gutcheck.Data.System' GatheredAt = Get-Date Manufacturer = $computer.Manufacturer Model = $computer.Model SerialNumber = $bios.SerialNumber OsCaption = $os.Caption OsDisplayVersion = $current.DisplayVersion OsBuildNumber = $os.BuildNumber OsUpdateBuildRevision = $current.UBR BiosVersion = $bios.SMBIOSBIOSVersion BiosReleaseDate = $bios.ReleaseDate ProcessorName = $cpu.Name ProcessorCores = $cpu.NumberOfCores ProcessorLogicalCount = $cpu.NumberOfLogicalProcessors TotalPhysicalMemoryBytes = $computer.TotalPhysicalMemory MemoryModules = $modules LastBootUpTime = $os.LastBootUpTime FastStartupEnabled = $power.HiberbootEnabled } } function ConvertTo-SystemFinding { [CmdletBinding()] [OutputType([psobject])] param( [AllowNull()]$Data, [hashtable]$Parameters = @{} ) New-ModelFinding -Data $Data -Parameters $Parameters New-OperatingSystemFinding -Data $Data -Parameters $Parameters New-BiosFinding -Data $Data -Parameters $Parameters New-ProcessorFinding -Data $Data -Parameters $Parameters New-RamInstalledFinding -Data $Data -Parameters $Parameters New-RamModuleFinding -Data $Data -Parameters $Parameters New-UptimeFinding -Data $Data -Parameters $Parameters } function New-ModelFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) $manufacturer = Get-DataProperty $Data 'Manufacturer' $model = Get-DataProperty $Data 'Model' if (-not $manufacturer -and -not $model) { return New-UnavailableFinding -Category System -Check (Get-Text 'Check.System.Model') ` -Hint (Get-Text 'Hint.System.TheMachineDidNotReport4') } New-Finding -Category System -Check (Get-Text 'Check.System.Model') -Severity INFO ` -Value ('{0} {1} (S/N {2})' -f $manufacturer, $model, (Get-DataProperty $Data 'SerialNumber')) } function New-OperatingSystemFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) $caption = Get-DataProperty $Data 'OsCaption' if (-not $caption) { return New-UnavailableFinding -Category System -Check (Get-Text 'Check.System.OS') ` -Hint (Get-Text 'Hint.System.TheOperatingSystemDidNot') } New-Finding -Category System -Check (Get-Text 'Check.System.OS') -Severity INFO -Value ((Get-Text 'Value.System.OperatingSystem') -f $caption, (Get-DataProperty $Data 'OsDisplayVersion'), (Get-DataProperty $Data 'OsBuildNumber'), (Get-DataProperty $Data 'OsUpdateBuildRevision')) } function New-BiosFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) $warnDays = Get-Parameter $Parameters 'BiosAgeWarnDays' 730 $failDays = Get-Parameter $Parameters 'BiosAgeFailDays' ([double]::MaxValue) $released = Get-DataProperty $Data 'BiosReleaseDate' if (-not $released) { return New-UnavailableFinding -Category System -Check (Get-Text 'Check.System.BIOS') ` -Hint (Get-Text 'Hint.System.TheMachineDidNotReport') } $ageDays = ((Get-DataProperty $Data 'GatheredAt') - [datetime]$released).TotalDays New-Finding -Category System -Check (Get-Text 'Check.System.BIOS') -Severity (Get-Severity $ageDays $warnDays $failDays) ` -Value ('{0} ({1:yyyy-MM-dd})' -f (Get-DataProperty $Data 'BiosVersion'), [datetime]$released) ` -Hint (Get-Text 'Hint.System.BIOSOlderThan2Years') } function New-ProcessorFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) $name = Get-DataProperty $Data 'ProcessorName' if (-not $name) { return New-UnavailableFinding -Category System -Check (Get-Text 'Check.System.CPU') ` -Hint (Get-Text 'Hint.System.TheMachineDidNotReport5') } New-Finding -Category System -Check (Get-Text 'Check.System.CPU') -Severity INFO -Value ((Get-Text 'Value.System.Processor') -f ([string]$name).Trim(), (Get-DataProperty $Data 'ProcessorCores'), (Get-DataProperty $Data 'ProcessorLogicalCount')) } function New-RamInstalledFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) # Graded downwards: here it is the small number that is the problem. $warnBelow = Get-Parameter $Parameters 'RamInstalledWarnBelowGB' 15 $failBelow = Get-Parameter $Parameters 'RamInstalledFailBelowGB' 7.5 $bytes = ConvertTo-Number (Get-DataProperty $Data 'TotalPhysicalMemoryBytes') if ($null -eq $bytes -or $bytes -le 0) { return New-UnavailableFinding -Category System -Check (Get-Text 'Check.System.RAMInstalled') ` -Hint (Get-Text 'Hint.System.TheMachineDidNotReport2') } $gb = [math]::Round($bytes / 1GB, 1) New-Finding -Category System -Check (Get-Text 'Check.System.RAMInstalled') -Severity (Get-SeverityBelow $gb $warnBelow $failBelow) ` -Value "$gb GB" ` -Hint (Get-Text 'Hint.System.OfficeTeamsBrowserBusinessApps') } function New-RamModuleFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) $modules = (Get-DataCollection $Data 'MemoryModules') if (-not $modules.Count) { return New-UnavailableFinding -Category System -Check (Get-Text 'Check.System.RAMModules') ` -Hint (Get-Text 'Hint.System.TheMachineDidNotReport3') } # A single module means single-channel, which is a real performance finding, but the # script reported it as INFO with a Hint rather than a WARN. Carried across unchanged. $hint = '' if ($modules.Count -eq 1) { $hint = (Get-Text 'Hint.System.SingleChannelMemory') } # Not a bare division: gathered data also reaches a Judge through a CliXML round trip, # where a capacity can arrive as text and dividing it would throw rather than report. $described = $modules | ForEach-Object { $capacity = ConvertTo-Number $_.CapacityBytes if ($null -eq $capacity) { '? GB @ {0} MHz' -f $_.ConfiguredClockSpeed } else { '{0} GB @ {1} MHz' -f ($capacity / 1GB), $_.ConfiguredClockSpeed } } New-Finding -Category System -Check (Get-Text 'Check.System.RAMModules') -Severity INFO -Value ($described -join ', ') -Hint $hint } function New-UptimeFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) $warnDays = Get-Parameter $Parameters 'UptimeWarnDays' 7 $failDays = Get-Parameter $Parameters 'UptimeFailDays' ([double]::MaxValue) $booted = Get-DataProperty $Data 'LastBootUpTime' if (-not $booted) { return New-UnavailableFinding -Category System -Check (Get-Text 'Check.System.Uptime') ` -Hint (Get-Text 'Hint.System.TheOperatingSystemDidNot2') } $days = ((Get-DataProperty $Data 'GatheredAt') - [datetime]$booted).TotalDays $fastStartup = Get-Text 'Value.System.FastStartupOff' if ((ConvertTo-Number (Get-DataProperty $Data 'FastStartupEnabled')) -eq 1) { $fastStartup = Get-Text 'Value.System.FastStartupOn' } New-Finding -Category System -Check (Get-Text 'Check.System.Uptime') -Severity (Get-Severity $days $warnDays $failDays) ` -Value ((Get-Text 'Value.System.Uptime') -f $days, $fastStartup) ` -Hint (Get-Text 'Hint.System.ShutDownWithFastStartup') } |