Private/Kinds/Power.ps1
|
# The Power Kind: whether the machine is allowed to go fast. # # A laptop that is throttled by its power plan, its power mode or by running on battery # looks identical to a slow laptop until someone checks. # The GUID Windows uses for the Power saver plan, and the overlay GUIDs for the power # mode slider. Invariant across languages, which is why they are matched rather than the # display text - the Target Machine estate is German. $script:PowerSaverSchemeGuid = 'a1841308-3541-4fab-bc81-f71556f20b4a' $script:PowerOverlayNames = @{ '961cc777-2547-4f9d-8174-7d86181b8a7a' = 'Best power efficiency' '3af9b8d9-7c97-431d-ad78-34a8bfea439f' = 'Better battery' '00000000-0000-0000-0000-000000000000' = 'Balanced' 'ded574b5-45a0-4f42-8737-46345c09c238' = 'Best performance' } function Get-PowerData { [CmdletBinding()] [OutputType([psobject])] param([hashtable]$Parameters = @{}) $scheme = '' try { $scheme = (powercfg /getactivescheme) -join ' ' } catch { } $schemes = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Power\User\PowerSchemes' -ErrorAction SilentlyContinue $battery = @(Get-CimInstance Win32_Battery -ErrorAction SilentlyContinue)[0] [pscustomobject]@{ PSTypeName = 'Gutcheck.Data.Power' ActiveSchemeDescription = $scheme ActiveOverlayGuid = $schemes.ActiveOverlayAcPowerScheme BatteryPresent = [bool]$battery BatteryStatus = $battery.BatteryStatus BatteryChargeRemaining = $battery.EstimatedChargeRemaining } } function ConvertTo-PowerFinding { [CmdletBinding()] [OutputType([psobject])] param( [AllowNull()]$Data, [hashtable]$Parameters = @{} ) New-PowerPlanFinding -Data $Data -Parameters $Parameters New-PowerModeFinding -Data $Data -Parameters $Parameters New-PowerSourceFinding -Data $Data -Parameters $Parameters } function New-PowerPlanFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) $description = [string](Get-DataProperty $Data 'ActiveSchemeDescription') if (-not $description) { return New-UnavailableFinding -Category Power -Check (Get-Text 'Check.Power.PowerPlan') ` -Hint (Get-Text 'Hint.Power.TheActivePowerPlanCould') } $severity = 'OK' if ($description -match $script:PowerSaverSchemeGuid) { $severity = 'WARN' } New-Finding -Category Power -Check (Get-Text 'Check.Power.PowerPlan') -Severity $severity ` -Value ($description -replace '^.*?:\s*', '') ` -Hint (Get-Text 'Hint.Power.PowerSaverPlanCapsCPU') } function New-PowerModeFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) # Absent on desktops and on Windows builds without the power mode slider. The script # reported nothing at all in that case, and so does this. $guid = Get-DataProperty $Data 'ActiveOverlayGuid' if (-not $guid) { return } $mode = $script:PowerOverlayNames["$guid".ToLowerInvariant()] if (-not $mode) { $mode = "$guid" } $severity = 'OK' if ($mode -match 'efficiency|battery') { $severity = 'WARN' } New-Finding -Category Power -Check (Get-Text 'Check.Power.PowerModePluggedIn') -Severity $severity -Value $mode ` -Hint (Get-Text 'Hint.Power.SetSettingsSystemPowerPower') } function New-PowerSourceFinding { [CmdletBinding()] param([AllowNull()]$Data, [hashtable]$Parameters) # A desktop has no battery and therefore no Finding, as in the script. if (-not (Get-DataProperty $Data 'BatteryPresent')) { return } $charge = Get-DataProperty $Data 'BatteryChargeRemaining' # Win32_Battery reports 1 for "discharging"; anything else means the machine is fed. $onAcPower = (ConvertTo-Number (Get-DataProperty $Data 'BatteryStatus')) -ne 1 if ($onAcPower) { $value = "AC adapter (charge $charge %)" $severity = 'OK' } else { $value = "Battery ($charge %)" $severity = 'WARN' } New-Finding -Category Power -Check (Get-Text 'Check.Power.PowerSource') -Severity $severity -Value $value ` -Hint (Get-Text 'Hint.Power.TestOnACOnBattery') } |