24

How can the new Night Light feature in Windows 10 (Pro) Creators Update be configured via the registry?

I'd like to auto configure new/updated installations when using my configuration management tool of choice (Chef). System inspection via Sysinternals Process Monitor shows a binary Data key getting updated deep in HKCU\Software\Microsoft\Windows\CurrentVersion\CloudStore\Cache\DefaultAccount\$$windows.data.bluelightreduction.settings\Current, but that's a big REG_BINARY blob and not very useful.

Help on a different registry, PowerShell, or other automation friendly way to configure the Night Light feature would be most appreciated!

4 Answers4

21

With a bunch of experimentation, I managed to more or less work out the format of that Registry value and wrote a PowerShell script to set it.

Tested on 21H2

And possibly appropriate for versions as early as the 2019 updates.

Function Set-BlueLightReductionSettings {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true)] [ValidateRange(0, 23)] [int]$StartHour,
        [Parameter(Mandatory=$true)] [ValidateSet(0, 15, 30, 45)] [int]$StartMinutes,
        [Parameter(Mandatory=$true)] [ValidateRange(0, 23)] [int]$EndHour,
        [Parameter(Mandatory=$true)] [ValidateSet(0, 15, 30, 45)] [int]$EndMinutes,
        [Parameter(Mandatory=$true)] [bool]$Enabled,
        [Parameter(Mandatory=$true)] [ValidateRange(1200, 6500)] [int]$NightColorTemperature
    )
    $data = (0x43, 0x42, 0x01, 0x00, 0x0A, 0x02, 0x01, 0x00, 0x2A, 0x06)
    $epochTime = [System.DateTimeOffset]::new((date)).ToUnixTimeSeconds()
    $data += $epochTime -band 0x7F -bor 0x80
    $data += ($epochTime -shr 7) -band 0x7F -bor 0x80
    $data += ($epochTime -shr 14) -band 0x7F -bor 0x80
    $data += ($epochTime -shr 21) -band 0x7F -bor 0x80
    $data += $epochTime -shr 28
    $data += (0x2A, 0x2B, 0x0E, 0x1D, 0x43, 0x42, 0x01, 0x00)
    If ($Enabled) {$data += (0x02, 0x01)}
    $data += (0xCA, 0x14, 0x0E)
    $data += $StartHour
    $data += 0x2E
    $data += $StartMinutes
    $data += (0x00, 0xCA, 0x1E, 0x0E)
    $data += $EndHour
    $data += 0x2E
    $data += $EndMinutes
    $data += (0x00, 0xCF, 0x28)
    $data += ($NightColorTemperature -band 0x3F) * 2 + 0x80
    $data += ($NightColorTemperature -shr 6)
    $data += (0xCA, 0x32, 0x00, 0xCA, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00)
    Set-ItemProperty -Path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\CloudStore\Store\DefaultAccount\Current\default$windows.data.bluelightreduction.settings\windows.data.bluelightreduction.settings' -Name 'Data' -Value ([byte[]]$data) -Type Binary
}

The format (or more properly a working format, since the Settings app can create multiple slightly different layouts):

  • 10 constant bytes
  • The last-modified Unix timestamp in seconds, mangled and spread across 5 bytes in what is probably a variable-length encoding:
    • One byte whose bits 0-6 are the timestamp's bits 0-6 but whose top bit 7 is always set
    • One byte whose bits 0-6 are the timestamps' 7-13 but whose top bit is always set
    • Likewise for two more sets of 7 bits
    • One final byte for timestamp bits 28-31, top bit not set
  • 8 constant bytes
  • Only if the schedule is enabled: constant bytes 0x02, 0x01
  • 3 constant bytes
  • The start hour
  • The constant byte 0x2E (presumably a field delimiter or type)
  • The start minute
  • 4 constant bytes
  • The end hour
  • The constant byte 0x2E again
  • 3 constant bytes
  • The night color temperature in Kelvin, two mangled bytes:
    • One byte whose low bit 0 is always unset, bits 1-6 are the temperature's bits 0-5, and top bit 7 is always set
    • One byte for the temperature's bit 6 and above, top bit not set
  • 10 constant bytes

Tested on 1703/1709

And possibly working as late as the 2018 updates.

Function Set-BlueLightReductionSettings {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true)] [ValidateRange(0, 23)] [int]$StartHour,
        [Parameter(Mandatory=$true)] [ValidateSet(0, 15, 30, 45)] [int]$StartMinutes,
        [Parameter(Mandatory=$true)] [ValidateRange(0, 23)] [int]$EndHour,
        [Parameter(Mandatory=$true)] [ValidateSet(0, 15, 30, 45)] [int]$EndMinutes,
        [Parameter(Mandatory=$true)] [bool]$Enabled,
        [Parameter(Mandatory=$true)] [ValidateRange(1200, 6500)] [int]$NightColorTemperature
    )
    $data = (2, 0, 0, 0)
    $data += [BitConverter]::GetBytes((Get-Date).ToFileTime())
    $data += (0, 0, 0, 0, 0x43, 0x42, 1, 0)
    If ($Enabled) {$data += (2, 1)}
    $data += (0xC2, 0x0A, 0x00) # Some users have reported this line necessary on 1709, was not needed originally
    $data += (0xCA, 0x14, 0x0E)
    $data += $StartHour
    $data += 0x2E
    $data += $StartMinutes
    $data += (0, 0xCA, 0x1E, 0x0E)
    $data += $EndHour
    $data += 0x2E
    $data += $EndMinutes
    $data += (0, 0xCF, 0x28)
    $tempHi = [Math]::Floor($NightColorTemperature / 64)
    $tempLo = (($NightColorTemperature - ($tempHi * 64)) * 2) + 128
    # Alternate proposed version (see edit history), possibly version-specific?: $tempLo = ($NightColorTemperature - ($tempHi * 64)) * 4
    $data += ($tempLo, $tempHi)
    $data += (0xCA, 0x32, 0, 0xCA, 0x3C, 0, 0)
    Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\$$windows.data.bluelightreduction.settings\Current' -Name 'Data' -Value ([byte[]]$data) -Type Binary
}

Using it

Save the script as a .ps1 file and follow the instructions in the Enabling Scripts section of the PowerShell tag wiki. You can then import the script's contents by dot-sourcing:

. ./bluelightmanagement.ps1

And then use the cmdlet-like function that it supplies:

Set-BlueLightReductionSettings -StartHour 7 -StartMinutes 0 -EndHour 21 -EndMinutes 15 -Enabled $true -NightColorTemperature 6000

the results

The Settings app even updates everything (except the strength/color slider) immediately if you have the blue light reduction page open when you run the command. For the slider to see the changes, you'll need to reopen the Settings app.

Ben N
  • 42,308
5

For anyone still looking for this in 2023, I was able to figure out the format used in the registry key value on Windows 11. For my purposes, I wanted to toggle it on/off from the command line. I was able to write a Node.js script to do so:

class Nightlight {
  // ...

async toggle(): Promise<void> { let newData: number[] const enabled = await this.enabled() const rawData = await this.getData() const data = hexToBytes(rawData.value)

if (enabled) {
  newData = new Array(41).fill(0)
  newData.splice(0, 22, ...data.slice(0, 22))
  newData.splice(23, 43 - 25, ...data.slice(25, 43))
  newData[18] = 0x13
} else {
  newData = new Array(43).fill(0)
  newData.splice(0, 22, ...data.slice(0, 22))
  newData.splice(25, 41 - 23, ...data.slice(23, 41))
  newData[18] = 0x15
  newData[23] = 0x10
  newData[24] = 0x00
}

for (let i = 10; i &lt; 15; i++) {
  if (newData[i] !== 0xff) {
    newData[i]++
    break
  }
}

}

Repo is here: https://github.com/nathanbabcock/nightlight-cli

To clarify, the difference between this and the accepted answer is that the top answer is for changing the "scheduled night light" setting while this is a manual on/off toggle.

4

Several hours of experiments and voila:
How to turn Night Light on/off in Win10 1903

The Registry key is:

HKCU\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\DefaultAccount\Current\default$windows.data.bluelightreduction.bluelightreductionstate\windows.data.bluelightreduction.bluelightreductionstate\

Value name: Data

To enable Night Light:

  1. Add bytes "10" and "00" to Data on 24 and 25 indexes respectively so all data length increases (don't change existing values, just add two more bytes)
  2. Increment value in 11 or 12 indexes by 1 (for example: if it was FF 01 than now it needs to be 00 02 respectively) Actually it seems it's time here and it's written in 8 bytes in little endian format, so you'll need also 13, 14, 15, 16, 17 and 18 indexes if you want to do it precise.

To disable Night Light:

  1. Remove bytes "10" and "00" from Data on 24 and 25 indexes respectively so all data length decreases
  2. Increment value in 11 or 12 indexes by 1 (for example: if it was FF 01 than now it needs to be 00 02 respectively)

I only needed to turn Night Light on/off for my program, so unfortunately all other options still need research. But it seems that the key option to all other tweaks to work (like changing temperature and schedule) is to properly increment time. These mods need to be done in another Data value in neighboring registry key windows.data.bluelightreduction.settings.

zx485
  • 2,337
hgrev
  • 41
  • 3
4

Update for Windows 10 2004.

Created mainly to set the time Minutes-exact. 19:57 is three Minutes before "Tagesschau" in Germany.

How to use: Edit this commented registry file to your start and end times. Activate night light in the control panel since I don't know whether this reg file is enough. Import it. You can change the strength in the control panel, as long as you don't change the time setting it will stick to the values you set, showing it as "activated until 06:57" in your main display control panel.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\CloudStore\Store\DefaultAccount\Current\default$windows.data.bluelightreduction.settings\windows.data.bluelightreduction.settings] ; 4 bytes whatever, CloudStore Signature ? "Data"=hex:43,42,01,00,
; Might still be 64 Bit filetime, last time the setting was changed in the control panel 0a,02,01,00,2a,06,c1,98,
; 11 bytes whatever 99,fb,05,2a,2b,0e,1f,43,42,01,00,
; Acivated flag. It is is missing (i.e. ce,14, is here) is is off! 02,01,
; 3 bytes whatever ca,14,0e,
; Starting Hour, 0x13 = 19 13,
; A constant 2e,
; Starting Minute, 0x39 = 57 39,
; 4 bytes whatever 00,ca,1e,0e,
; Ending Hour, 0x06 = 6 Uhr 06,
; A constant 2e,
; Ending Minute 39,
; 3 bytes constant 00,cf,28,
; Strength, here "33". 9e,4a,
; 10 bytes whatever (why so many trailing zeroes?) ca,32,00,ca,3c,00,00,00,00,00

Ben N
  • 42,308