Skip to content

Instantly share code, notes, and snippets.

@SaltwaterC
Last active September 9, 2025 18:23
Show Gist options
  • Select an option

  • Save SaltwaterC/57af2ddaa317a61ff19ba7fb99f8672b to your computer and use it in GitHub Desktop.

Select an option

Save SaltwaterC/57af2ddaa317a61ff19ba7fb99f8672b to your computer and use it in GitHub Desktop.
Lenovo ThinkPad Backlight Control

Lenovo ThinkPad Backlight Control

Note: for a full desktop experience, use this software that I put together to solve this problem https://github.com/SaltwaterC/KeyboardBacklightForLenovo

Quick and dirty PowerShell script for controlling backlight on newer Lenovo ThinkPads. Makes use of Keyboard_Core.dll. Inspired by this Reddit post. At the time of writing this, that post is the top Google result for something that doesn't work.

It automatically detects the version in ThinkKeyboardAddin directory and it supports passing the backlight level via command line argument. By passing the -verbose flag it prints what it does behind the scenes.

The script won't change the keyboard backlight status if the passed status is already set. This makes repeated invocation less annoying as it won't trigger an on-screen notification about the state change when there is no state to change.

.\thinkpad-backlight.ps1 -verbose
Keyboard backlight status is 0 (0=Off, 1=Dim, 2=Bright)
Keyboard backlight set to level 2 (0 = Off, 1 = Dim, 2 = Bright)

.\thinkpad-backlight.ps1 -level 1 -verbose
Keyboard backlight status is 2 (0=Off, 1=Dim, 2=Bright)
Keyboard backlight set to level 1 (0 = Off, 1 = Dim, 2 = Bright)

.\thinkpad-backlight.ps1 -level 1 -verbose
Keyboard backlight status is 1 (0=Off, 1=Dim, 2=Bright)

Additionally, this may be compiled into an executable with ps2exe:

ps2exe -inputFile .\thinkpad-backlight.ps1 -outputFile .\thinkpad-backlight.exe -noConsole

The -noConsole flag makes the executable to be callable outside the shell without momentarily spawning a console window.

# === Settings ===
param (
[ValidateSet(0,1,2)]
[int]$level = 2, # Default to 2 (Bright)
[switch]$verbose
)
# Base path for Lenovo Vantage Addin
[string]$basePath = 'C:\ProgramData\Lenovo\Vantage\Addins\ThinkKeyboardAddin'
try {
# Get the latest version directory
$versionDir = Get-ChildItem -Path $basePath -Directory |
Sort-Object Name -Descending |
Select-Object -First 1
if (-not $versionDir) {
throw "No version directories found in $basePath"
}
# Construct full path to the DLL
[string]$core = Join-Path $versionDir.FullName 'Keyboard_Core.dll'
if (-Not (Test-Path $core)) {
throw "Keyboard_Core.dll not found at $core"
}
# Load the DLL without emitting anything
$null = Add-Type -Path $core -ErrorAction Stop
# Create the control object
$control = New-Object -TypeName 'Keyboard_Core.KeyboardControl'
# Prepare variables for output parameters
$status = 0
$refStatus = [ref]$status
$dummy = $null
$refDummy = [ref]$dummy
# Get current keyboard backlight status
$null = $control.GetKeyboardBackLightStatus($refStatus, $refDummy)
if ($verbose) {
Write-Host "Keyboard backlight status is $($refStatus.Value) (0=Off, 1=Dim, 2=Bright)"
}
# Change status only if different from desired level
if ($refStatus.Value -ne $level) {
$null = $control.SetKeyboardBackLightStatus($level, $refDummy)
if ($verbose) {
Write-Host "Keyboard backlight set to level $level (0 = Off, 1 = Dim, 2 = Bright)"
}
}
# Explicitly end try block without output
$null
}
catch {
Write-Host "Error: $_"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment