blog

Schedule A Task When PC Switches From Charging To AC Power [Windows]

Schedule-1As I was going over some issues others have had – I came across a fascinating question in the Microsoft Answer newsgroups. The user essentially wanted to trigger the execution of a task when the computer goes from being on battery to AC and vice versa. Since the Windows Task Scheduler does not include the ability to set a power source change trigger, you can’t use what Microsoft has written for this. I set out to find a way to make this possible.

Option1: Use PowerShell
On Windows 7 specifically – there are a number PowerShell scripts for power events in the following folder:

C:\Windows\diagnostics\system\Power

The script that is of main interest is PowerConfig.ps1 file that appears to access parts of the Windows API structures. The main one accessed is SYSTEM_POWER_CAPABILITIES, but the one you want is SYSTEM_BATTERY_STATE and that’s not included with these scripts (and the accompanying DLL). There is a way to make it work, I’m sure, but it’s beyond the scope of this article.

So, enter the trusty WMI interface to get this information with Powershell.

Using the Get-WMI-Object cmdlet, setup a powershell script like this:

Function Check-BatteryState {
param($Laptop=$env:computername)
$Bstatus = (Get-WmiObject -Class Win32_Battery -ea 0).BatteryStatus
if($Bstatus) {
    switch ($Bstatus)
    {
    1 { “Discharging” }
    2 { “ONACMaybeNotCharging” }
    3 { “FullyCharged” }
    4 { “Low” }
    5 { “Critical” }
    6 { “Charging” }
    7 { “ChargingAndHigh” }
    8 { “ChargingAndLow” }
    9 { “ChargingAndCritical ” }
    10 { “UnknownState” }
    11 { “PartiallyCharged” }            
    }
}
}
Check-BatteryState;

Thanks to Techibee for most of the above code snippit. You can download the above file, CheckBattery.ps1 if it’s easier for you to work with.

The output of the above script looks like the following:

Schedule-2

I’m choosing to return basic and predictable text from the above function that can can be acted on. From this you can take that text and run a Scheduled Task every minute that checks on the return value. You could even modify the above script directly to save the current state and launch a process if that state is different.

Option 2: Write your own tool
This second option is much more advanced, but if I were to approach this problem programmatically, I would create a C++ application to make a call to the “System.Windows.Forms.SystemInformation.PowerStatus” namespace in the following way:

public:
static property PowerStatus^ PowerStatus {
PowerStatus^ get ();
}

From there you can pull out the BatteryChargeStatus property and, based on the return value, execute a process. That process itself would be configured either by way of and INI file or in the registry. In addition to the above, you could use the Windows (32/64?) API function named GetSystemPowerStatus in most any program language to pull out power state information and do the same.

Another Method
Speaking strictly of a server (and not laptop scenario), many power management and alerting applications on Windows allow you to trigger the launch of a task based on a power event. I’m familiar with the facilities offered in the PowerChute application (provided by APC).

No matter what you choose, keep in mind that the next version of Windows may expose this as a trigger, so make sure you check for that before dumping hours into solving a problem like this when you don’t need too. Above all, I would like to know how it goes for you.