PowerShell/WMI power management
<p>I'm new to Windows power management and even newer to WMI, but always welcome a learning opportunity.</p>

<p>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.</p>

<p>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.)</p>

<h2>My question</h2>

<p>What's the proper way to programmatically discover the GUID for each plan, subgroup, action, available value, etc?</p>

<h2>Reference</h2>

<p>In BATCH using the powercfg.exe tool the commands would be:</p>

<pre><code>:: 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
</code></pre>

<p>My PowerShell/WMI solution is this:</p>

<pre><code>$CommonArgs = @{"namespace"="root\cimv2\power"}
$CommonArgs += $PSBoundParameters

function Set-PowerSettingDataIndexValue
{
    &lt;#
    .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 &lt;SCHEME_GUID&gt; &lt;SUB_GUID&gt; &lt;SETTING_GUID&gt; &lt;SETTING_INDEX&gt;'
        and
        'POWERCFG /SETDCVALUEINDEX &lt;SCHEME_GUID&gt; &lt;SUB_GUID&gt; &lt;SETTING_GUID&gt; &lt;SETTING_INDEX&gt;'
        except that the &lt;SUB_GUID&gt; is implied by the $PowerSettingDefinitionGuid
    .Example
        Set-PowerSettingDataIndexValue "{8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c}" "{7648efa3-dd9c-4e3e-b566-50f929386280}" 3
    #&gt;

    [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
{
    &lt;#
    .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
    #&gt;

    # 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
</code></pre>