Home > Net >  Required registry changes to adjust Windows screen brightness?
Required registry changes to adjust Windows screen brightness?

Time:09-10

Windows 10 21H2 19044.1949
Powershell 7.2.6

I wrote a script to adjust the Windows screen brightness, based on

https://winaero.com/change-screen-brightness-registry-tweak/
https://devblogs.microsoft.com/scripting/get-windows-power-plan-settings-on-your-computer-by-using-powershell/
https://stackoverflow.com/a/35844259/308851 (the function 'Take-Permissions' was copied from here, unmodified)

However, it doesn't do the job. The appropriate registry values get set as desired, but the screen brightness doesn't actually change. When I open Windows settings->System->Screen, the brightness values are still unchanged. If I change them manually there, the registry values get updated accordingly. What am I missing?

# Show / set brightness

param ( [parameter(Mandatory=$false)]
        [Int32]
        [ValidateRange(0,100)]
        $number = -1 
      );

  function Take-Permissions {
    # SOURCE: https://stackoverflow.com/a/35844259/308851
    # Developed for PowerShell v4.0
    # Required Admin privileges
    # Links:
    #   http://shrekpoint.blogspot.ru/2012/08/taking-ownership-of-dcom-registry.html
    #   http://www.remkoweijnen.nl/blog/2012/01/16/take-ownership-of-a-registry-key-in-powershell/
    #   https://powertoe.wordpress.com/2010/08/28/controlling-registry-acl-permissions-with-powershell/

    param($rootKey, $key, [System.Security.Principal.SecurityIdentifier]$sid = 'S-1-5-32-545', $recurse = $true)

    switch -regex ($rootKey) {
        'HKCU|HKEY_CURRENT_USER'    { $rootKey = 'CurrentUser' }
        'HKLM|HKEY_LOCAL_MACHINE'   { $rootKey = 'LocalMachine' }
        'HKCR|HKEY_CLASSES_ROOT'    { $rootKey = 'ClassesRoot' }
        'HKCC|HKEY_CURRENT_CONFIG'  { $rootKey = 'CurrentConfig' }
        'HKU|HKEY_USERS'            { $rootKey = 'Users' }
    }

    ### Step 1 - escalate current process's privilege
    # get SeTakeOwnership, SeBackup and SeRestore privileges before executes next lines, script needs Admin privilege
    $import = '[DllImport("ntdll.dll")] public static extern int RtlAdjustPrivilege(ulong a, bool b, bool c, ref bool d);'
    $ntdll = Add-Type -Member $import -Name NtDll -PassThru
    $privileges = @{ SeTakeOwnership = 9; SeBackup =  17; SeRestore = 18 }
    foreach ($i in $privileges.Values) {
        $null = $ntdll::RtlAdjustPrivilege($i, 1, 0, [ref]0)
    }

    function Take-KeyPermissions {
        param($rootKey, $key, $sid, $recurse, $recurseLevel = 0)

        ### Step 2 - get ownerships of key - it works only for current key
        $regKey = [Microsoft.Win32.Registry]::$rootKey.OpenSubKey($key, 'ReadWriteSubTree', 'TakeOwnership')
        $acl = New-Object System.Security.AccessControl.RegistrySecurity
        $acl.SetOwner($sid)
        $regKey.SetAccessControl($acl)

        ### Step 3 - enable inheritance of permissions (not ownership) for current key from parent
        $acl.SetAccessRuleProtection($false, $false)
        $regKey.SetAccessControl($acl)

        ### Step 4 - only for top-level key, change permissions for current key and propagate it for subkeys
        # to enable propagations for subkeys, it needs to execute Steps 2-3 for each subkey (Step 5)
        if ($recurseLevel -eq 0) {
            $regKey = $regKey.OpenSubKey('', 'ReadWriteSubTree', 'ChangePermissions')
            $rule = New-Object System.Security.AccessControl.RegistryAccessRule($sid, 'FullControl', 'ContainerInherit', 'None', 'Allow')
            $acl.ResetAccessRule($rule)
            $regKey.SetAccessControl($acl)
        }

        ### Step 5 - recursively repeat steps 2-5 for subkeys
        if ($recurse) {
            foreach($subKey in $regKey.OpenSubKey('').GetSubKeyNames()) {
                Take-KeyPermissions $rootKey ($key '\' $subKey) $sid $recurse ($recurseLevel 1)
            }
        }
    }

    Take-KeyPermissions $rootKey $key $sid $recurse
}

### MAIN ###

# get the GUID of the current active power plan:
$guid = (Get-CimInstance -classname Win32_PowerPlan -Namespace "root\cimv2\power" -Filter "IsActive='True'").InstanceID.tostring() 
$regex = [regex]"{(.*?)}$"
$planGuid = $regex.Match($guid).groups[1].value

# set the registry path values:
$regPath0="HKLM"
$regPath1=$regPath0 ":\"
$regPath2= "SYSTEM\CurrentControlSet\Control\Power\User\PowerSchemes\" $planGuid "\7516b95f-f776-4464-8c53-06167f40cc99\aded5e82-b909-4619-9949-f5d71dac0bcb"
$regPath=$regPath1 $regPath2
$regProp1="ACSettingIndex";
$regProp2="DCSettingIndex";
  
if ($number -eq -1) {
    Write-Host "Current brightness:" (Get-ItemProperty $regPath $regProp2).$regProp2
} else {
    # initially, Admin has no rights to modify this key:
    $AdminGroupSid="S-1-5-32-544"
    Take-Permissions $regPath0 $regPath2 $AdminGroupSid $false

    Set-ItemProperty $regPath $regProp1 $number
    Set-ItemProperty $regPath $regProp2 $number

    # verify the new setting:
    Write-Host "Brightness set to:" (Get-ItemProperty $regPath $regProp2).$regProp2
}

CodePudding user response:

As mentionned by Daniel in the comment, the changes in the registry are not taken into account. I suppose when you change the settings from the Control Panel Windows is doing another stuff in the background. It reminds me this question where the OP had to run a P/Invoke to disable immediately the Stick Key.

Anyway, it looks very complicated for this simple task. Why not using WMI ? https://docs.microsoft.com/fr-fr/windows/win32/wmicoreprov/wmisetbrightness-method-in-class-wmimonitorbrightnessmethods

$brightness = 75
$timeout = 0
$(Get-WmiObject -ns root/wmi -class wmiMonitorBrightNessMethods).WmiSetBrightness($timeout,$brightness)

Edit: without using the depreciated Get-WMiObject: Get-CimInstance -Namespace "root/WMI" -ClassName "WmiMonitorBrightnessMethods" | Invoke-CimMethod -MethodName "WmiSetBrightness" -Arguments @{Timeout=$timeout; Brightness=$brightness;}

CodePudding user response:

Short script to set and/or query monitor brightness:

param ( [parameter(Mandatory=$false)]
        [Int32]
        [ValidateRange(0,100)]
        $number = -1 
      );

if ($number -ne -1) {
    Get-CimInstance -Namespace "root/WMI" -ClassName "WmiMonitorBrightnessMethods" | 
    Invoke-CimMethod -MethodName "WmiSetBrightness" -Arguments @{Timeout=0; Brightness=$number;} |
    Out-Null
}
Write-Host Brightness is  (Get-Ciminstance -Namespace root/WMI -ClassName WmiMonitorBrightness).CurrentBrightness %
  • Related