How to check if monitor timeout is set to 'never'?

401 Views Asked by At

I know I can set the monitor timeout to 'never' using powercfg -change monitor-timeout-ac 0

However, how can I check what the value of monitor timeout is? Without setting it to a new value?

2

There are 2 best solutions below

0
On

Note: powercfg.exe accepts - and /-prefixed parameter names interchangeably, and the case of the name doesn't matter; this answer uses - and all-lowercase names.

tl;dr

Unfortunately, this is more cumbersome than it should be:

  • Quick-and-dirty approach (assumes that your Windows display language is English):

    powercfg /query | Select-String -Context 7 'Turn off display'
    
    • Visually parse the last two lines, which will look something like this; the values are hex numbers, expressed in seconds. 0x00000000 means "Never":

      Current AC Power Setting Index: 0x00000000
      Current DC Power Setting Index: 0x000000b4
      
  • Programmatic, language-independent GUID approach:

    ((powercfg -query @(
      (powercfg -getactivescheme) -replace '^.+ \b([0-9a-f]+-[^ ]+).+', '$1'
      '7516b95f-f776-4464-8c53-06167f40cc99'
      '3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e'
    ))[-3] -replace '^.+: ') / 60
    
    • This outputs the AC display timeout in (decimal) minutes, as you would pass it to powercfg -change monitor-timeout-ac ...; again, 0 represents "Never".

Read on for an explanation and a convenience function that wraps the functionality.


Santiago's answer is a good start:

  • It demonstrates the - unfortunate - need to use a path of GUIDs to drill down to a setting of interest with powercfg.exe's -query (-q) parameter; in other words: you unfortunately can not use the same symbolic names such as monitor-timeout-ac that the -change (-x) parameter supports.

    • Additionally, the values are expressed (a) in hexadecimal form and (b) reported in seconds rather than the minute values you pass to -change (-x); however, in both cases 0 represents "Never"

    • -change (-x) doesn't support all settings, however; targeting the remaining ones requires the -setacvalueindex / -setdcvalueindex parameters, which - like -query - requires a path of GUIDs, and specifying the values in seconds.

  • While the scheme-internal groups and settings have fixed GUIDs, the top-level GUID varies, based on the active scheme:

    • The active scheme can be one of the predefined ones (which have well-known GUIDs), or one of any number of potential custom ones (which are assigned new GUIDs on creation).

    • powercfg -list lists all available schemes, powercfg -getactivescheme the active one.


Therefore, for instance, querying the active scheme's monitor-timeout-ac and monitor-timeout-dc values requires the following cumbersome solution (the fixed, schema-internal GUIDs are taken from the list in the bottom section):

# Get the "Turn off display after" setting's values.
[UInt32] $acValue, [Uint32] $dcValue = 
  (powercfg -query @(
    # Determine the active scheme's GUID
    (powercfg -getactivescheme) -replace '^.+ \b([0-9a-f]+-[^ ]+).+', '$1'
    # The fixed "Display" subgroup's GUID
    '7516b95f-f776-4464-8c53-06167f40cc99'
    # The fixed "Turn off display after" setting's GUID
    '3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e'
  ))[-3, -2] -replace '^.+: '

# Output both the AC and the DC value in *minutes*.
[pscustomobject] @{
  AC = $acValue / 60
  DC = $dcValue / 60
}

The above is obviously cumbersome; convenience function Get-PowerCfg eases the pain (source code in the next section; invoke it with -? for help).

E.g., running Get-PowerCfg with the Power saver scheme in effect outputs the following on Windows 11; values are in minutes; 0 represents "Never":

Scheme            : Power saver
monitor_timeout   : @{AC=5; DC=2}
disk_timeout      : @{AC=20; DC=5}
standby_timeout   : @{AC=15; DC=10}
hibernate_timeout : @{AC=0; DC=0}

Get-PowerCfg function source code:

function Get-PowerCfg {
  <#
.SYNOPSIS
  Gets the most important power (sleep) settings.
.DESCRIPTION
  Gets the most important power (sleep) settings on Windows.
  
  Defaults to the active power scheme (plan), but a different one may be
  specified, either by GUID or by name (pattern).
  Use * to target all available schemes.

  Output units are minutes; 0 means "Never".

  Add -Raw to get raw `powercfg.exe -query` output, which includes *all*
  settings, expressed as hex numbers, and - for time-based units - in seconds.

  To change a settings value for the active scheme, use:
    powercfg -change {<settings>-ac | <settings>-dc} <value-in-minutes>
  where <settings> is a property name as reflected in the output, except with
  "_", replaced with "_" e.g. "monitor-timeout-ac"

.EXAMPLE
Get-PowerCfg

Get the active scheme's settings.

.EXAMPLE
Get-PowerCfg *

Get the settings for all available schemes.

.EXAMPLE
Get-PowerCfg bal*

Get the settings for schemes whose name starts with "bal"

.EXAMPLE
Get-PowerCfg -Raw

Get the active scheme's raw settings (complete set), as reported by
`powercfg -query`
#>

  [CmdletBinding()]
  param(
    [SupportsWildcards()]
    [string] $Scheme, # defaults to the active one
    [switch] $Raw     # request raw powercfg -query output
  )

  if ($env:OS -ne 'Windows_NT') { throw 'This command runs on Windows only.' }

  $settingGuidsToNames = [ordered] @{
    '3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e' = 'monitor_timeout'
    '6738e2c4-e8a5-4a42-b16a-e040e769756e' = 'disk_timeout'
    '29f6c1db-86da-48c5-9fdb-f2b67b1f44da' = 'standby_timeout'
    '9d7815a6-7ee4-497e-8888-515a05f02364' = 'hibernate_timeout'
  }

  $allSchemes = 
  @(powercfg.exe -list) -ne '' | 
    Select-Object -Skip 2 | 
    ForEach-Object { 
      $null, $guid, $name, $other = ($_ -split '[:()]').Trim()
      [pscustomobject] @{ Name = $name; Guid = $guid; Active = [bool] $other } 
    }

  if (-not $Scheme) {
    $matchingSchemes = $allSchemes.Where({ $_.Active }, 'First')[0]
  }
  elseif ($Scheme -as [guid]) {
    # scheme GUID given
    $matchingSchemes = $allSchemes.Where({ $_.Guid = $Scheme }, 'First')[0]
  }
  else {
    # scheme name given
    $matchingSchemes = $allSchemes | Where-Object Name -Like $Scheme
  }
  if (-not $matchingSchemes) { throw "No power scheme matching '$Scheme' found." }

  foreach ($matchingScheme in $matchingSchemes) {
    $allSettingsText = powercfg.exe -query $matchingScheme.Guid
    if ($Raw) { $allSettingsText; continue }
    $paragraphs = ($allSettingsText -join "`n") -split '\n{2}' -match '\S'
    $out = [ordered] @{ Scheme = $matchingScheme.Name }
    $settingGuidsToNames.GetEnumerator() | 
      ForEach-Object {
        $guid = $_.Key
        $lines = $paragraphs.Where({ $_ -match ('\b{0}\b' -f $guid) }, 'First')[0] -split '\n'
        [Uint32] $acValue, [Uint32] $dcValue = $lines[-2, -1] -replace '^.+: '
        $out[$_.Value] = [pscustomobject] @{
          AC = $acValue / 60
          DC = $dcValue / 60
        }
      }
    [pscustomobject] $out
  }
}

List of all fixed, schema-internal GUIDs, for subgroups and their settings, as of Windows 11:

# Unindented = SUBGROUP
#      Indented = SETTING
Name                          Guid
----                          ----
Hard disk                     0012ee47-9041-4b5d-9b77-535fba8b1442
    Turn off hard disk after      6738e2c4-e8a5-4a42-b16a-e040e769756e
Internet Explorer             02f815b5-a5cf-4c84-bf20-649d1f75d3d8
    JavaScript Timer Frequency    4c793e7d-a264-42e1-87d3-7a0d2f523ccd
Desktop background settings   0d7dbae2-4294-402a-ba8e-26777e8488cd
    Slide show                    309dce9b-bef4-4119-9921-a851fb12f0f4
Wireless Adapter Settings     19cbb8fa-5279-450e-9fac-8a3d5fedd0c1
    Power Saving Mode             12bbebe6-58d6-4636-95bb-3217ef867c1a
Sleep                         238c9fa8-0aad-41ed-83f4-97be242c8f20
    Sleep after                   29f6c1db-86da-48c5-9fdb-f2b67b1f44da
    Allow hybrid sleep            94ac6d29-73ce-41a6-809f-6363ba21b47e
    Hibernate after               9d7815a6-7ee4-497e-8888-515a05f02364
    Allow wake timers             bd3b718a-0680-4d9d-8ab2-e1d2b4ac806d
USB settings                  2a737441-1930-4402-8d77-b2bebba308a3
    USB selective suspend setting 48e6b7a6-50f5-4782-a5d4-53bb8f07e226
Power buttons and lid         4f971e89-eebd-4455-a8de-9e59040e7347
    Start menu power button       a7066653-8d6c-40a8-910e-a1f54b84c7e5
PCI Express                   501a4d13-42af-4429-9fd1-a8218c268e20
    Link State Power Management   ee12f906-d277-404b-b6da-e5fa1a576df5
Processor power management    54533251-82be-4824-96c1-47b60b740d00
    Minimum processor state       893dee8e-2bef-41e0-89c6-b55d0929964c
    Maximum processor state       bc5038f7-23e0-4960-96da-33abaf5935ec
Display                       7516b95f-f776-4464-8c53-06167f40cc99
    Turn off display after        3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e
    Display brightness            aded5e82-b909-4619-9949-f5d71dac0bcb
    Dimmed display brightness     f1fbfde2-a960-4165-9f88-50667911ce96
    Enable adaptive brightness    fbd9aa66-9553-4097-ba44-ed6e9d65eab8
Multimedia settings           9596fb26-9850-41fd-ac3e-f7c3c00afd4b
    When sharing media            03680956-93bc-4294-bba6-4e0f09bb717f
    Video playback quality bias   10778347-1370-4ee0-8bbd-33bdacaade49
    When playing video            34c7b99f-9a6d-4b3c-8dc7-b6693b78cef4
Battery                       e73a048d-bf27-4f12-9731-8b2076e8891f
    Critical battery notification 5dbb7c9f-38e9-40d2-9749-4f8a0e9f640f
    Critical battery action       637ea02f-bbcb-4015-8e2c-a1c7b9c0b546
    Low battery level             8183ba9a-e910-48da-8769-14ae6dc1170a
    Critical battery level        9a66d8d7-4ff7-4ef9-b5a2-5a326ca2a469
    Low battery notification      bcded951-187b-4d05-bccc-f7e51960c258
    Low battery action            d8742dcb-3e6a-4b3c-b3fe-374623cdcf06
    Reserve battery level         f3c5027d-cd16-4930-aa6b-90db844a8f00
1
On

Perhaps this PowerShell example works for you, supposedly the GUIDs shouldn't change. The values would be represented in Minutes.

powercfg @(
    '/query'
    '381b4222-f694-41f0-9685-ff5bb260df2e'
    '7516b95f-f776-4464-8c53-06167f40cc99'
    '3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e'
) | Select-Object -Last 2 -Skip 1 | & {
    begin { $out = [ordered]@{} }
    process {
        $key, $val = $_.Split(':').Trim()
        $val = [int] $val / 60

        if ($val -eq 0) {
            $val = 'Never'
        }

        $out[$key] = $val
    }
    end {
        $out
    }
}