I'm new to Windows power management and even newer to WMI, but always welcome a learning opportunity.
Using PowerShell and WMI I want to set the "High Performance" power plan's "Lid close action", "Power button action" and "Sleep button action" to the "Do nothing" option and finally set the active power plan to the "High Performance" power plan. I have a working solution, but I have my doubts as to whether it is a proper solution.
The crux of my problem is that all of the plans, subgroups, actions, available values, etc. are identified with GUIDs and I've read that it is possible for these GUIDs to vary from system to system (especially if applied via group policy.) In my solution I've managed to avoid hard coding GUIDs only to end up hard coding values such as "Power and lid buttons", "Lid close action", "Do nothing", etc. which may or may not vary in non-English builds of Windows. (I'm using Windows 8.1 by the way.)
What's the proper way to programmatically discover the GUID for each plan, subgroup, action, available value, etc?
In BATCH using the powercfg.exe tool the commands would be:
:: Set the lid close action, power button action and sleep button action to do nothing
powercfg /SETACVALUEINDEX 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 4f971e89-eebd-4455-a8de-9e59040e7347 5ca83367-6e45-459f-a27b-476b1d01c936 0
powercfg /SETDCVALUEINDEX 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 4f971e89-eebd-4455-a8de-9e59040e7347 5ca83367-6e45-459f-a27b-476b1d01c936 0
powercfg /SETACVALUEINDEX 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 4f971e89-eebd-4455-a8de-9e59040e7347 7648efa3-dd9c-4e3e-b566-50f929386280 0
powercfg /SETDCVALUEINDEX 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 4f971e89-eebd-4455-a8de-9e59040e7347 7648efa3-dd9c-4e3e-b566-50f929386280 0
powercfg /SETACVALUEINDEX 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 4f971e89-eebd-4455-a8de-9e59040e7347 96996bc0-ad50-47ec-923b-6f41874dd9eb 0
powercfg /SETDCVALUEINDEX 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 4f971e89-eebd-4455-a8de-9e59040e7347 96996bc0-ad50-47ec-923b-6f41874dd9eb 0
powercfg /SETACTIVE 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
My PowerShell/WMI solution is this:
$CommonArgs = @{"namespace"="root\cimv2\power"}
$CommonArgs += $PSBoundParameters
function Set-PowerSettingDataIndexValue
{
<#
.Synopsis
Sets the value associated with a specified power setting for both AC and DC power.
.Description
This function is somewhat similar to running the two commands
'POWERCFG /SETACVALUEINDEX <SCHEME_GUID> <SUB_GUID> <SETTING_GUID> <SETTING_INDEX>'
and
'POWERCFG /SETDCVALUEINDEX <SCHEME_GUID> <SUB_GUID> <SETTING_GUID> <SETTING_INDEX>'
except that the <SUB_GUID> is implied by the $PowerSettingDefinitionGuid
.Example
Set-PowerSettingDataIndexValue "{8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c}" "{7648efa3-dd9c-4e3e-b566-50f929386280}" 3
#>
[CmdletBinding()]
param (
[parameter(Mandatory=$true)]
[string]$PowerPlanGuid,
[parameter(Mandatory=$true)]
[string]$PowerSettingDefinitionGuid,
[parameter(Mandatory=$true)]
[string]$SettingIndexValue
)
$PowerSettingDataIndexAC = Get-CimInstance -ClassName Win32_PowerSettingDataIndex -Filter "InstanceID = 'Microsoft:PowerSettingDataIndex\\$PowerPlanGuid\\AC\\$PowerSettingDefinitionGuid'" @CommonArgs
Set-CimInstance -InputObject $PowerSettingDataIndexAC -Property @{ SettingIndexValue=$SettingIndexValue }
$PowerSettingDataIndexDC = Get-CimInstance -ClassName Win32_PowerSettingDataIndex -Filter "InstanceID = 'Microsoft:PowerSettingDataIndex\\$PowerPlanGuid\\DC\\$PowerSettingDefinitionGuid'" @CommonArgs
Set-CimInstance -InputObject $PowerSettingDataIndexDC -Property @{ SettingIndexValue=$SettingIndexValue }
}
function Set-PowerButtonAndLidActions
{
<#
.Synopsis
Sets the power button, sleep button and lid actions to do nothing effectively disabling these buttons.
.Description
This function modifies every existing power plan to effectively disable the power button, sleep button and
lid action. Additonally this function will set the "high performance" power plan as the active power plan.
.Example
Set-PowerButtonAndLidActions
#>
# Get the power setting subgroup where the element name is 'Power buttons and lid'
$PowerSettingSubgroup = Get-CimInstance -ClassName Win32_PowerSettingSubgroup -Filter "ElementName = 'Power buttons and lid'" @CommonArgs
# Get the power setting definitions for 'Lid close action', 'Power button action' and 'Sleep button action'
$PowerSettingDefinitionLidCloseAction = Get-CimAssociatedInstance -InputObject $PowerSettingSubgroup | where { $_.ElementName -eq "Lid close action" }
$PowerSettingDefinitionPowerButtonAction = Get-CimAssociatedInstance -InputObject $PowerSettingSubgroup | where { $_.ElementName -eq "Power button action" }
$PowerSettingDefinitionSleepButtonAction = Get-CimAssociatedInstance -InputObject $PowerSettingSubgroup | where { $_.ElementName -eq "Sleep button action" }
# Extract the GUID from each action's instance ID
$PowerSettingDefinitionLidCloseActionGuid = $PowerSettingDefinitionLidCloseAction.InstanceID -replace '.*({[^}]+})', '$1'
$PowerSettingDefinitionPowerButtonActionGuid = $PowerSettingDefinitionPowerButtonAction.InstanceID -replace '.*({[^}]+})', '$1'
$PowerSettingDefinitionSleepButtonActionGuid = $PowerSettingDefinitionSleepButtonAction.InstanceID -replace '.*({[^}]+})', '$1'
# Get the value of the 'Do Nothing' option for each power setting definition
$LidCloseActionDoNothing = Get-CimInstance -Query "SELECT * FROM Win32_PowerSettingDefinitionPossibleValue WHERE ElementName = 'Do nothing' AND InstanceID LIKE '%\\$PowerSettingDefinitionLidCloseActionGuid\\%'" @CommonArgs
$PowerButtonActionDoNothing = Get-CimInstance -Query "SELECT * FROM Win32_PowerSettingDefinitionPossibleValue WHERE ElementName = 'Do nothing' AND InstanceID LIKE '%\\$PowerSettingDefinitionPowerButtonActionGuid\\%'" @CommonArgs
$SleepButtonActionDoNothing = Get-CimInstance -Query "SELECT * FROM Win32_PowerSettingDefinitionPossibleValue WHERE ElementName = 'Do nothing' AND InstanceID LIKE '%\\$PowerSettingDefinitionSleepButtonActionGuid\\%'" @CommonArgs
$p = Get-CimInstance -ClassName Win32_PowerPlan -Filter "ElementName = 'High performance'" @CommonArgs
# Extract the GUID from the power plan's InstanceID property
$PlanGuid = $p.InstanceID -replace '.*({[^}]+})', '$1'
Set-PowerSettingDataIndexValue -PowerPlanGuid $PlanGuid -PowerSettingDefinitionGuid $PowerSettingDefinitionLidCloseActionGuid $LidCloseActionDoNothing.SettingIndex
Set-PowerSettingDataIndexValue -PowerPlanGuid $PlanGuid -PowerSettingDefinitionGuid $PowerSettingDefinitionPowerButtonActionGuid $PowerButtonActionDoNothing.SettingIndex
Set-PowerSettingDataIndexValue -PowerPlanGuid $PlanGuid -PowerSettingDefinitionGuid $PowerSettingDefinitionSleepButtonActionGuid $SleepButtonActionDoNothing.SettingIndex
Invoke-CimMethod -InputObject $p -MethodName Activate | Out-Null
}
Set-PowerButtonAndLidActions
You can use Get-CIMInstance
to list pretty much all of these. The power plans are all in the Win32_PowerPlan
class, so:
Get-CimInstance -classname Win32_PowerPlan -Namespace "root\cimv2\power"
That will list all of the plans on the computer. You can find all this information at https://msdn.microsoft.com/en-us/library/dd904531(v=vs.85).aspx. There's even PowerShell examples.
From there you just have to parse out the info that you need. The ElementName
property shows what somebody would see if they went to the Power Settings GUI in the control panel. The InstanceID
is where you'll find the GUID, though you may need to do something like:
Get-CimInstance -Namespace "root\cimv2\power" -class Win32_PowerPlan|Select ElementName,@{l='GUID';e={$_.instanceid.substring(20)}}
The rest should be found in Win32_PowerSetting
and Win32_PowerSettingSubgroup
. You should be able to explore that site to find other related classes to get you what info you need.