Use PowerShell to Detect Power State and to Set Power Plan

Use PowerShell to Detect Power State and to Set Power Plan

  • Comments 5
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to detect the power state on his laptop and to set the appropriate power plan.

Microsoft Scripting Guy, Ed Wilson, is here. This evening in Oslo, Norway, the Scripting Wife and I are attending the Microsoft Technology User Group meeting. The meeting runs from 18:00 until 20:00 (CET). Interestingly enough, the lows in Oslo and in Charlotte, North Carolina, are about the same. The big difference is the 30-degree temperature between high and low in Charlotte. Oh well, and the other big difference is a bit of snow! WOO HOO!!!

Detect power state by using PowerShell

To detect whether or not my laptop is running on battery, I can query the Win32_Battery WMI class. This WMI class is in the Root\CimV2 WMI namespace and has been around since forever. There is nothing special about this class. The only thing is to ensure that my laptop actually populates information in the class—and that the information is reliable.

In the past, I have had laptops in which the Win32_Battery WMI class did not populate at all when the laptop was plugged into electricity; it only became available when the laptop ran on battery. There is another WMI class—Win32_Portablebattery. This WMI class also derives from Cim_Battery, but it provides a bit more information than Win32_Battery. On the other hand, Win32_Battery provides information about recharge status. The differences are shown here.

PS C:\> $b = Get-CimClass win32_battery

PS C:\> $p = Get-CimClass win32_portablebattery

PS C:\> Compare-Object $b.CimClassProperties.name $p.CimClassProperties.name

InputObject                                SideIndicator

-----------                                -------------

CapacityMultiplier                         =>

Location                                   =>

ManufactureDate                            =>

Manufacturer                               =>

MaxBatteryError                            =>

BatteryRechargeTime                        <=

ExpectedBatteryLife                        <=

The battery is discharging

If the laptop runs on the battery, the BatteryStatus reports 1, which means that “The battery is discharging.” The other conditions are a bit more complicated. The following chart details the meaning of the status of the battery.

Value

Meaning

 1

The battery is discharging.

 2

The system has access to AC so no battery is being discharged. However, the battery is not necessarily charging.

 3

Fully Charged

 4

Low

 5

Critical

 6

Charging

 7

Charging and High

 8

Charging and Low

 9

Charging and Critical

 10

Undefined

 11

Partially Charged

 

For my purpose, I use the value like a Boolean—1 means ”on battery,” everything else means “plugged in” (at least for my script). Here is how I obtain the battery status.

(Get-CimInstance win32_battery).batterystatus

Set the appropriate power plan

To set the power plan on my laptop, I use the Win32_PowerPlan WMI class (see yesterday’s article) and I call the Activate method. All I really need to do is to add a bit of logic, then retrieve the appropriate power plan, and activate it. I decided, right now, that I will use Power Saver if the battery is discharging (1), High Performance if the battery is fully charged (3) and Balanced, if the battery is any other status. The script is a simple If / ElseIF / Else type of construction. Here is the code.

SetPowerSaverPlan.ps1

 

If ((Get-CimInstance win32_battery).batterystatus -eq 1)

  {

   $p = Get-CimInstance -Name root\cimv2\power -Class win32_PowerPlan `

    -Filter "ElementName = 'Power Saver'"      

    Invoke-CimMethod -InputObject $p -MethodName Activate }

Elseif ((Get-CimInstance win32_battery).batterystatus -eq 3)

  {

   $p = Get-CimInstance -Name root\cimv2\power -Class win32_PowerPlan `

    -Filter "ElementName = 'High performance'" 

    Invoke-CimMethod -InputObject $p -MethodName Activate }

Else

 {

   $p = Get-CimInstance -Name root\cimv2\power -Class win32_PowerPlan `

    -Filter "ElementName = 'Balanced'"  

    Invoke-CimMethod -InputObject $p -MethodName Activate }

What I do not know, yet, is how often the script will select High Performance. This is because, with the Windows Battery Conditioning technology, the battery does not always fully charge. At times, for example, on my laptop, the battery stops charging at 98 percent or so—and I do not know if THAT condition reports as fully charged (3). Therefore, after a bit of testing, I may eliminate the ElseIf condition, and do a simple If / Else and use the Else condition to set the full power plan.

If I want to check to see what power plan gets applied as a result of the above script, I can do a simple query to check for the active power plan, as shown here.

Get-CimInstance -Name root\cimv2\power -Class win32_PowerPlan  -Filter "isactive = true" |

  Select-Object elementname

Well, that is about it for now. We have a lot of stuff to do and to see here in Oslo before the user group meeting this evening.

Join me tomorrow when I will talk about changing the power plan on servers running Windows Server 2008 R2 and Windows Server 2012.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • thanks for share.

  • Same but using a switch statement:

    switch ((Get-CimInstance Win32_Battery).BatteryStatus) {

       1 { $filter = "ElementName = 'Power Saver'" }

       3 { $filter = "ElementName = 'High Performance'" }

       default { $filter = "ElementName = 'Balanced'" }

    }

    $p = Get-CimInstance -Name root\cimv2\power -Class Win32_PowerPlan -Filter $filter

    [void](Invoke-CimMethod -InputObject $p -MethodName Activate)

  • I wish there was instrumentation for interruptible power supplies still :(

  • @Troy

    Unfortunately interruptible power supplies have not yet been invented.  Perhaps by 2050 or so we will have them.  Until then we have to make due with Uninterruptible Power Supplies or UPS systems.  As such we can query the state of the power using WMI and even more with Windows APIs.

    Some vendors provide tools and extension  classes so we can read back all UPS info.

    Try posting in your UPS vendors forum for instructions.

    Until then we will wait for the much needed IPS.

  • @Troy there used to be a WMI class in XP msdn.microsoft.com/.../aa394503(v=vs.85).aspx