powercfg on Windows: power plans, sleep diagnostics and battery reports

powercfg.exe is the command-line front end for the Windows power subsystem. It reads and writes power plans, reports which sleep states the firmware actually offers, names the process that is keeping a machine awake, and generates the battery, energy and sleep-study reports that Control Panel never exposes.

For a sysadmin the interesting part is not the laptop battery. It is the branch-office server that suspends itself at 02:00 and drops its monitoring heartbeat, the workstation that wakes every night because a NIC is armed for wake-on-LAN, and the 32 GB hiberfil.sys sitting on a 128 GB system SSD. All three are one powercfg query away from an answer.

Microsoft documents the switches. What follows is the part the reference page leaves out: which switch answers which question, what the output actually looks like, where the report files land when you run elevated, and the two places where the current documentation page will hand you an invalid parameter.

Applies to: Windows 10, Windows 11, Windows Server 2016 / 2019 / 2022


Quick answer

Four commands answer most power questions on a machine you have just connected to. Run them from an elevated prompt: the last two return nothing useful without administrator rights.

rem Which plan is actually in force - the Control Panel radio button can lag behind
powercfg /getactivescheme

rem What sleep states this hardware and firmware really support
powercfg /a

rem What is holding the machine awake right now
powercfg /requests

rem What woke it last time
powercfg /lastwake

/getactivescheme prints one line with the GUID and the friendly name of the plan in force:

Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e  (Balanced)

What powercfg does

Windows stores power configuration as a set of schemes. Each scheme is a GUID holding a tree of subgroups and settings, and every setting carries two values: one for AC and one for DC. powercfg is the only supported way to reach the settings that Control Panel hides, and it is the only way to reach any of it from a script.

OptionWhat it doesElevation
/list, /lLists every power scheme with its GUID; the active one is marked with an asteriskNo
/getactiveschemePrints only the active schemeNo
/setactive GUID, /sSwitches the active scheme; accepts an alias instead of a GUIDYes
/query [scheme] [sub], /qDumps every setting in a scheme or subgroup with its AC and DC indexNo
/change setting minutes, /xSets one of the eight common timeouts on the active schemeYes
/aliasesMaps friendly aliases such as SCHEME_MIN onto their GUIDsNo
/availablesleepstates, /aReports which sleep states exist, and the exact reason each missing one is unavailableYes
/requestsLists the process, service or driver power requests blocking display off or sleepYes
/requestsoverrideOverrides a specific caller’s power request, or lists current overridesYes
/lastwakeReports what woke the system from the last sleep transitionYes
/waketimersEnumerates active wake timers and the scheduled task behind each oneYes
/devicequery flagLists devices matching a criterion such as wake_armed or wake_programmableNo
/deviceenablewake, /devicedisablewakeArms or disarms one device for waking the systemYes
/hibernate on|off, /hEnables or disables hibernation; also accepts /size percent and /type reduced|fullYes
/energyObserves the system for 60 seconds and writes energy-report.htmlYes
/batteryreportWrites battery-report.html covering design capacity, full charge capacity and usage historyNo
/sleepstudyWrites sleepstudy-report.html for the last 3 days; up to 28 with /durationYes
/systempowerreportModern-standby power transition reportYes
/duplicatescheme, /changename, /export, /import, /deleteBuild, rename, move and remove custom plansYes

Practical examples

1. A server suspends itself overnight

The problem: SRV-PROD-01 in a branch office goes unreachable between 02:00 and 07:00. It is a desktop-class machine repurposed as a server, so it shipped with the Balanced plan and its default sleep timeout.

The solution: set the sleep, hibernate and disk timeouts on AC to zero, which powercfg reads as never, and leave the monitor timeout short so the screen still blanks.

These four commands write to the currently active scheme only. Confirm which scheme that is first, otherwise you may be editing a plan nothing uses.

rem Read before you write - /change never asks which plan you meant
powercfg /getactivescheme

rem 0 means never. -ac is mains power, -dc is battery
powercfg /change standby-timeout-ac 0
powercfg /change hibernate-timeout-ac 0
powercfg /change disk-timeout-ac 0

rem The display can still blank - that costs nothing and saves the panel
powercfg /change monitor-timeout-ac 15
Warning: /change silently targets the active scheme. If a GPO or a login script runs powercfg /setactive afterwards, the timeouts you just set are no longer the ones in force, and nothing in the output tells you.

2. Standardise the plan across a fleet without pasting GUIDs

The problem: a build script has to force High performance on every imaged machine, but the friendly plan names are localised and the GUIDs are unreadable in a batch file.

The solution: use the built-in aliases. They are the same on every Windows install and in every language.

rem SCHEME_MIN = minimum power savings = High performance. No GUID, no locale problem
powercfg /setactive SCHEME_MIN
powercfg /getactivescheme

The three built-in plan aliases are SCHEME_MAX for Power saver, SCHEME_BALANCED for Balanced and SCHEME_MIN for High performance. Run powercfg /aliases to see the full list, which also covers subgroups and individual settings.

For a custom plan, clone an existing one rather than editing a built-in scheme. /duplicatescheme prints the new GUID, which you then feed to /changename and /export:

rem Clone Balanced - the new GUID is printed, copy it into the next two commands
powercfg /duplicatescheme SCHEME_BALANCED

rem Name it so the next admin knows why it exists
powercfg /changename 7b3ba6c2-9f1a-4c8d-b0e1-2d4c5f6a7b81 "SRV-PROD Always On" "No sleep, no disk spindown"

rem Export once, import on every other host
powercfg /export C:\bat\srv-alwayson.pow 7b3ba6c2-9f1a-4c8d-b0e1-2d4c5f6a7b81
powercfg /import C:\bat\srv-alwayson.pow

To undo it, delete the scheme by GUID. A scheme that is currently active cannot be deleted, so switch away first.

powercfg /setactive SCHEME_BALANCED
powercfg /delete 7b3ba6c2-9f1a-4c8d-b0e1-2d4c5f6a7b81

3. The machine refuses to sleep

The problem: a workstation never enters sleep and the display never turns off, even though the timeouts are correct. Something is holding a power request.

The solution: powercfg /requests names the caller. It groups output by request type, and prints None. for every category that is clear.

powercfg /requests
DISPLAY:
[PROCESS] \Device\HarddiskVolume3\Program Files\Zoom\bin\Zoom.exe
Video Conference in progress.

SYSTEM:
[DRIVER] Realtek High Definition Audio (HDAUDIO\FUNC_01&VEN_10EC)
An audio stream is currently in use.

AWAYMODE:
None.

EXECUTION:
None.

PERFBOOST:
None.

Once you have the caller name, you can either close the process or override its request permanently. The override takes the caller type and the exact name from the /requests output, followed by the request types to suppress.

rem Stop this one process from blocking display off and sleep
powercfg /requestsoverride PROCESS Zoom.exe DISPLAY SYSTEM

rem List every override currently in place
powercfg /requestsoverride

rem Remove it again - repeat the caller with no request types
powercfg /requestsoverride PROCESS Zoom.exe

Valid caller types are PROCESS, SERVICE and DRIVER. Valid request types are DISPLAY, SYSTEM and AWAYMODE. If the request is coming from a process you did not expect, cross-reference the executable name with tasklist and taskkill before overriding anything.

4. The machine wakes at 03:00 every night

The problem: a workstation wakes on its own overnight. Users see it running in the morning; the event log shows a Kernel-Power wake but not a cause an admin can act on.

The solution: there are only two possible causes, a wake timer or an armed device, and powercfg covers both. Start with what woke it last time.

rem What actually woke it - the Description line is the device or the timer
powercfg /lastwake

rem Which timers are armed right now, and which scheduled task set each one
powercfg /waketimers
Timer set by [SERVICE] \Device\HarddiskVolume3\Windows\System32\svchost.exe (UnistackSvcGroup)
expires at 3:12:05 AM on 9/7/2026.
  Reason: NT TASK\Microsoft\Windows\UpdateOrchestrator\Reboot

The Reason line is a scheduled task path. That is the fix point: clear the Wake the computer to run this task flag on that task rather than disabling wake timers wholesale. See schtasks for querying task properties from CMD.

If /waketimers is empty, a device is armed. List the armed devices, then disarm the one you do not want.

rem Only devices currently allowed to wake the system - usually a NIC, a mouse or a keyboard
powercfg /devicequery wake_armed

rem Everything that COULD be armed, for comparison
powercfg /devicequery wake_programmable

rem Disarm one. The name must match the /devicequery output exactly, quotes included
powercfg /devicedisablewake "Intel(R) Ethernet Connection (7) I219-LM"

rem And to put it back
powercfg /deviceenablewake "Intel(R) Ethernet Connection (7) I219-LM"
Warning: if nothing is armed, powercfg /devicequery wake_armed prints the single word NONE. A script that loops over that output will happily try to disable a device called NONE, so filter that line out before piping the result into /devicedisablewake.

5. hiberfil.sys is eating the system SSD

The problem: a 128 GB system SSD on a server has lost a large chunk of free space to C:\hiberfil.sys, and the file cannot be deleted from Explorer or from an elevated prompt.

The solution: the file is owned by the kernel and only powercfg releases it. On a server that never hibernates, turn hibernation off and the file disappears on the next boot cycle.

rem Check first - if Hibernate is already unavailable there is no file to reclaim
powercfg /a

rem Removes hiberfil.sys entirely
powercfg /hibernate off

rem Shrink instead of removing: percent of installed RAM, minimum 50 per the docs
powercfg /hibernate /size 50

rem Reduced keeps Fast Startup working with a much smaller file
powercfg /hibernate /type reduced
Common mistake: powercfg /hibernate off also disables Fast Startup and hybrid sleep, because both are built on the hiberfile. On a laptop that means a cold boot every time and no resume from hibernation. On a server it is usually the right call; on a user machine, prefer /hibernate /type reduced.

If the free space still does not come back, the volume itself may be the problem rather than the hiberfile. The DISKPART guide covers the cases where Disk Management reports the wrong free space.

6. Generate the three report files

The problem: a user reports two hours of battery life on a machine rated for eight, and you need evidence before raising a warranty case.

The solution: the battery report shows design capacity against current full charge capacity, which is the number a vendor will accept. Always pass /output with an explicit path.

rem Battery health and usage history. /duration limits the history to N days
powercfg /batteryreport /output C:\bat\battery-report.html /duration 14

rem Energy efficiency analysis. Leave the machine idle for the full 60 seconds
powercfg /energy /output C:\bat\energy-report.html /duration 60

rem Modern standby drain analysis, last 3 days by default, up to 28
powercfg /sleepstudy /output C:\bat\sleepstudy-report.html /duration 7
Result: three self-contained HTML files you can attach to a ticket. The battery report is the useful one for hardware claims: compare DESIGN CAPACITY with FULL CHARGE CAPACITY in the Installed batteries table.

Hidden gems

Your report file is in System32. Without /output, powercfg writes the report to the current working directory. An elevated CMD prompt opens in C:\Windows\System32, so powercfg /batteryreport run as administrator leaves battery-report.html in a directory that the logged-on user cannot write to and rarely thinks to look in. Every report switch accepts /output; use it every time.

The documentation has a typo that costs you a support call. The current Microsoft Learn page lists the enable switch as /deviceenableawake. The binary does not accept that spelling; the archived Windows Server reference and powercfg /? both give /deviceenablewake, with no second “a”. Copy from the current page and you get an invalid parameter error on a command that looks correct.

/energy needs an idle machine. The default observation window is 60 seconds and it starts immediately. Typing in another window, an antivirus scan, or a browser left open will all show up as errors and warnings in the report. Run it, then leave the machine alone for a minute.

[DRIVER] Legacy Kernel Caller is not a driver. When /requests reports that name, the request came in through an older kernel API that does not carry an identifiable caller. Chasing the name is a dead end. Look instead at what is running: a mounted ISO, an audio stream or a USB device in use is the usual source.

Combine /aliases with /query. Aliases work anywhere a GUID is accepted, including subgroups and individual settings, so you can dump one subgroup of the active plan without a single GUID on the command line.

rem SUB_SLEEP is the alias for the Sleep subgroup - dump only that part of the active plan
powercfg /query SCHEME_CURRENT SUB_SLEEP

Cross-shell equivalent

There is no PowerShell cmdlet for power plans. What PowerShell adds is structure: parse the powercfg /list output once and you get objects you can filter, sort and export instead of a wall of text.

# Turn powercfg /list into objects. Group 1 is the GUID, group 2 is the friendly name.
# A trailing asterisk on the line marks the active scheme.
powercfg /list | Select-String 'Power Scheme GUID: ([0-9a-f-]{36})\s+\((.+?)\)' | ForEach-Object {
    [pscustomobject]@{
        GUID   = $_.Matches[0].Groups[1].Value
        Name   = $_.Matches[0].Groups[2].Value
        Active = $_.Line.TrimEnd().EndsWith('*')
    }
}
GUID                                 Name             Active
----                                 ----             ------
381b4222-f694-41f0-9685-ff5bb260df2e Balanced           True
8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c High performance  False
a1841308-3541-4fab-bc81-f71556f20b4a Power saver       False

WMI exposes the same plans as real objects through the Win32_PowerPlan class, which lives in the root\cimv2\power namespace rather than the default one. This is the cleanest way to read the plan list remotely.

# Note the non-default namespace - omit it and the class is simply not found
Get-CimInstance -Namespace root\cimv2\power -ClassName Win32_PowerPlan |
    Select-Object ElementName, IsActive
Note: read with CIM, write with powercfg. The Activate method on Win32_PowerPlan is documented, but on current Windows builds Invoke-CimMethod -MethodName Activate frequently returns “This method is not implemented in any class”. Use powercfg /setactive for the write half and the behaviour is consistent everywhere.

Batch scripts often need only the active GUID. CMD gets it in one line, because the GUID is always the fourth whitespace-delimited token of the /getactivescheme output:

rem tokens=4 lands on the GUID: Power / Scheme / GUID: / 381b4222-...
rem At an interactive prompt use %a. Inside a .bat file, double it to %%a
for /f "tokens=4" %a in ('powercfg /getactivescheme') do @set "ACTIVE=%a"
echo %ACTIVE%

Where this matters

  • Repurposed desktops running as servers. Consumer hardware ships with Balanced and a sleep timeout; one /change standby-timeout-ac 0 ends a class of intermittent outage that looks like a network fault.
  • Wake-on-LAN deployments. /devicequery wake_armed tells you in one line whether the NIC is actually armed, before you spend an afternoon debugging magic packets.
  • Laptop warranty claims. The battery report’s design versus full charge capacity figures are what a vendor asks for, and they take thirty seconds to produce.
  • Reclaiming space on small system disks. Disabling hibernation frees a file the size of a large fraction of installed RAM, which on a 32 GB host is real capacity.
  • Kiosk, signage and lab machines. A scripted /setactive SCHEME_MIN plus zeroed timeouts is the entire power configuration, applied identically on every image.
  • Patch windows that never happen. /waketimers shows whether the Update Orchestrator task can actually wake the machine, which decides whether an overnight maintenance window works at all.

Tips and limitations

  • /requests, /lastwake, /waketimers, /energy, /sleepstudy and every write operation need an elevated prompt. Run without elevation and several of them return an empty or misleading result rather than an access-denied error.
  • Timeout values in /change are minutes, and 0 means never. Values in /setacvalueindex and /setdcvalueindex are decimal integers even though /query prints them as hexadecimal.
  • Group Policy wins. If power settings are managed by GPO, a local powercfg change survives only until the next policy refresh, and nothing in the command output warns you.
  • Device names in /deviceenablewake and /devicedisablewake must match the /devicequery output character for character, including the manufacturer string in parentheses.
  • On modern standby hardware the classic S3 sleep state does not exist. powercfg /a is the authoritative answer for what a given machine supports, and it states the reason each unavailable state is missing.
  • Plan friendly names are localised. Scripts should match on GUIDs or aliases, never on the name string.

Official documentation


Related tools

  • Event Log Analyzer: paste a Kernel-Power or Power-Troubleshooter event and read it alongside the /lastwake output.
  • System Tools: the rest of the Windows administration utilities on zaur.it, grouped in one place.

Related guides