public/Test-SystemHealth.ps1
|
function Test-SystemHealth { <# .SYNOPSIS Runs a consolidated Linux system health check. .DESCRIPTION Collects health indicators from disk, memory, failed services, package updates, and reboot state. .PARAMETER WarningDiskPercent Disk usage threshold considered warning level. .PARAMETER WarningMemoryPressure Memory pressure threshold considered warning level. .EXAMPLE Test-SystemHealth Returns a health summary for the local system. .LINK https://github.com/Skatterbrainz/linuxtools/blob/master/docs/Test-SystemHealth.md #> [CmdletBinding()] param( [parameter()][int]$WarningDiskPercent = 85, [parameter()][int]$WarningMemoryPressure = 60 ) try { $warnings = @() $checks = [ordered]@{} $diskRows = df -P | Select-Object -Skip 1 $maxDiskUse = 0 foreach ($row in $diskRows) { $parts = $row.Split(' ') | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } if ($parts.Count -ge 6) { $usePct = [int](($parts[4]).TrimEnd('%')) if ($usePct -gt $maxDiskUse) { $maxDiskUse = $usePct } } } $checks['MaxDiskPercent'] = $maxDiskUse if ($maxDiskUse -ge $WarningDiskPercent) { $warnings += "Disk usage warning: $maxDiskUse%" } $memoryPressure = 0 if (Test-Path '/proc/pressure/memory') { $pressureLine = Get-Content '/proc/pressure/memory' | Where-Object { $_ -like 'some *' } | Select-Object -First 1 if ($pressureLine -match 'avg10=(?<avg10>[0-9.]+)') { $memoryPressure = [math]::Round([double]$matches['avg10'], 2) } } $checks['MemoryPressureAvg10'] = $memoryPressure if ($memoryPressure -ge $WarningMemoryPressure) { $warnings += "Memory pressure warning: avg10=$memoryPressure" } $failedServiceCount = 0 if (Get-Command -Name systemctl -ErrorAction SilentlyContinue) { $failedServices = systemctl --failed --no-legend 2>$null | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } $failedServiceCount = @($failedServices).Count } $checks['FailedServices'] = $failedServiceCount if ($failedServiceCount -gt 0) { $warnings += "Failed services: $failedServiceCount" } $pendingUpdates = 0 if (Get-Command -Name Get-PackageUpdates -ErrorAction SilentlyContinue) { $pendingUpdates = @(Get-PackageUpdates).Count } $checks['PendingUpdates'] = $pendingUpdates if ($pendingUpdates -gt 0) { $warnings += "Pending package updates: $pendingUpdates" } $rebootPending = $false if (Get-Command -Name Test-RebootPending -ErrorAction SilentlyContinue) { $rebootValue = Test-RebootPending $rebootPending = [bool]$rebootValue } $checks['RebootPending'] = $rebootPending if ($rebootPending) { $warnings += 'Reboot pending' } $score = 100 $score -= ($warnings.Count * 15) if ($score -lt 0) { $score = 0 } $status = if ($warnings.Count -eq 0) { 'Healthy' } elseif ($warnings.Count -le 2) { 'Warning' } else { 'Critical' } $checksObject = [pscustomobject]$checks [pscustomobject]@{ HealthScore = $score Status = $status MaxDiskPercent = $maxDiskUse MemoryPressureAvg10 = $memoryPressure FailedServices = $failedServiceCount PendingUpdates = $pendingUpdates RebootPending = $rebootPending WarningCount = $warnings.Count Warnings = $warnings Checks = $checksObject } } catch { Write-Error $($_.Exception.Message -join(';')) } } |