:::: MENU ::::

How to Enable Wake Timers

Each scheduled task in Windows has the option to wake the computer out of sleep in order to run. But in order for this feature to work, there is at least one other prerequisite that has to be met, and that is to enable the “Allow Wake Timers” setting on the active power plan.

PowerOptions

(Start > Control Panel\Hardware and Sound\Power Options)

 

How would you enable wake timers automatically?

Unfortunately, there isn’t a GPO setting (that I am aware of) that will allow you to easily configure this setting.

PowerOptionGPO

Looking at the registry, there is a key which could be used to enable\disable wake timers, but the path depends on the power plan GUID, sleep category GUID, and the wake timer GUID.

HKLM:\SYSTEM\CurrentControlSet\Control\Power\User\PowerSchemes\(Power Plan GUID)\(Sleep Category GUID)\(Allow Wake Timer GUID)
ACSettingIndex = 0 or 1 –When plugged in.

DCSettingIndex= 0 or 1 –When running on battery.

Where a value of 1 is enable, and 0 is disable.

Because using the registry requires knowledge of these GUIDs, a more elegant solution would be to use the built-in powercfg.exe utility that is available on all modern copies of Windows. This utility has the ability to gather information from all configured power schemes, and can actually set values for the wake timer setting as well.

More information on powercfg can be found here.

Here is a PowerShell script that uses powercfg.exe to enable the “Allow Wake Timers” setting for all power schemes on a computer. It can be deployed via GPO as a logon\logoff script or by any endpoint management system.

The script is fairly short, so I’ll explain how it works.

1. The first task is to gather the information on all the power schemes configured on the computer. This is done by calling powercfg.exe /LIST, which outputs text similar to the image below.

PowerCFG

This text is immediately piped to select-string which creates a list containing each power scheme.

$PowerSchemes = (powercfg.exe /LIST) | Select-String "power scheme guid" -List

The Allow Wake Timers GUID is gathered in a similar manner.

$AllowWakeTimersGUID = ((powercfg.exe /q) | Select-String "(Allow wake timers)").tostring().split(" ") | where {($_.length -eq 36) -and ([guid]$_)}

2. The entire Power scheme list is then passed through a for loop, where each power scheme is reduced to its GUID.

$PowerSchemeGUID = $PowerScheme.tostring().split(" ") | where {($_.length -eq 36) -and ([guid]$_)}

 

3. Finally, the arguments for powercfg.exe are constructed using the GUIDs. There are two different arguments: one for AC and the other for DC, I assume these correspond to the registry values mentioned earlier. And powercfg.exe is called with these arguments, one after another.

 

foreach ($PowerScheme in $PowerSchemes) {
   $PowerSchemeGUID = $PowerScheme.tostring().split(" ") | where {($_.length -eq 36) -and ([guid]$_)}
   foreach ($Argument in ("/SETDCVALUEINDEX $PowerSchemeGUID SUB_SLEEP $AllowWakeTimersGUID 1","/SETACVALUEINDEX $PowerSchemeGUID SUB_SLEEP $AllowWakeTimersGUID 1")) {
    Start-Process powercfg.exe -ArgumentList $Argument -Wait -Verb runas -WindowStyle Hidden}}

 

Conclusion

This script seems to work well on Windows 8.1 and Windows 7, but there are a few things to keep in mind:

First of all, you must run this script (like all scripts on this site) “as administrator”. Otherwise, you will be hit with a barrage of UAC prompts, one for each time powercfg.exe is called.

Secondly, the wake timer setting exists on a per power plan basis. Each power plan: “Balanced”, “Power Saver”, “High Performance”, etc… contains the “Allow Wake Timers” setting. The implication is that while “Allow Wake Timers” may be enabled for one power plan, it could be disabled on another at the same time. The power plan that is active while a computer is put into sleep dictates the machine’s ability to respond to wake timers.

My script enables the Allow Wake Timers setting for all power plans. This way, it doesn’t matter if a different plan becomes active any point in time, the computer will always have the ability to respond to wake timers. If having wake timers enabled for certain power plans, while also having it disabled on others is important for your needs, you will have to edit the script. An easy way to do this is to change the “power scheme guid” string from line 1 to the name of your target power plan(s), such as “Balanced”.

Finally, if you would like to disable wake timers for all power plans on a machine, change the 1’s in the script into 0’s (view line #6 below).

   foreach ($Argument in ("/SETDCVALUEINDEX $PowerSchemeGUID SUB_SLEEP $AllowWakeTimersGUID 0","/SETACVALUEINDEX $PowerSchemeGUID SUB_SLEEP $AllowWakeTimersGUID 0")) {

Script(s) Used in This Post:

Enable Wake Timers (//adameyob.com/scripts/enable-wake-timers/)



Subscribe
Notify of

12 Comments
Inline Feedbacks
View all comments

Hi Adam, This is exact what I`m looking for! But I get an error when running the script as administrator: You cannot call a method on a null-valued expression. At C:\Temp\PowerSettings.ps1:2 char:90 + $AllowWakeTimersGUID = ((powercfg.exe /q) | Select-String “(Allow wake timers)”).tostring <<<< ().split(" ") | where {($_.length -eq 36) -and ([guid]$_)} + CategoryInfo : InvalidOperation: (tostring:String) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull You cannot call a method on a null-valued expression. At C:\Temp\PowerSettings.ps1:5 char:41 + $PowerSchemeGUID = $PowerScheme.tostring <<<< ().split(" ") | where {($_.length -eq 36) -and ([guid]$_)} + CategoryInfo : InvalidOperation: (tostring:String) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull… Read more »

Hi Adam,

When I run powercfg.exe /q from cmd I get a lot of information, and the descriptions are in Dutch, so I don`t see Allow wake timers. I think I have to replace that by the Dutch word.

Kind Regards

If you’re not worried about users having custom power plans, you can use powercfg.exe to set all the default power plans to allow wake timers using the friendly names for the GUIDs.

It would look like:

powercfg /SETACINDEXVALUE SCHEME_BALANCED SUB_SLEEP RTCWake 1
powercfg /SETACINDEXVALUE SCHEME_MIN SUB_SLEEP RTCWake 1
powercfg /SETACINDEXVALUE SCHEME_MAX SUB_SLEEP RTCWake 1

(I only did it for when the machines are on AC, but you could also use /SETDCINDEXVALUE this way.)

This script doesn’t modify the Wake Timers setting in Win10. Any ideas as to how to modify your script to support Win10, or any leads as to where to look?

Hey there Adam,

Thanks for sharing your script. It saved me quite a bit of work and it was well put together.

I do know how to execute PowerShell scripts. I am trying to mass deploy a wake event to a school that utilizes laptop carts, to have them turn on at a certain time for software deployment and patching.

[cid:image002.png@01D1805A.7C7D6660]

The test Win10 machine I am using does not apply the settings. I wonder what’s different between this win10 machine and yours that’s making the success vary…

Thanks.

Thanks for the reply. In the end I spun up a Win10 VM and it works. Not sure why it wasn’t working on the laptop, but all is well. Thanks!

Here’s another option to enable wake timers on AC for the active power plan:

FOR /f “tokens=1,2,3,4” %%I IN (‘powercfg.exe /getactivescheme’) DO ( SET GUID=%%L )
powercfg /setacvalueindex %GUID% SUB_SLEEP RTCWAKE 1