If you game on Windows and switch between SDR desktop and HDR titles, manual toggling gets old fast. I built a lightweight PowerShell HDR Switcher that watches for Steam games and toggles HDR automatically.
Why I built it
- No heavy third-party tools
- Runs continuously with simple logic
- Fast reaction (~3s polling)
- Built around the native Windows HDR hotkey
How it works
- A small C# block is loaded in PowerShell to send keyboard events.
- The script triggers
Win + Alt + B(Windows HDR toggle). - Every 3 seconds it checks running processes under Steam library paths.
- Game detected ? toggle HDR on. No game detected ? toggle HDR off.
Script
# Define the HDR Toggle Function
$code = @"
using System;
using System.Runtime.InteropServices;
public class Keyboard {
[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
public static void ToggleHDR() {
keybd_event(0x5B, 0, 0, 0); keybd_event(0x12, 0, 0, 0); keybd_event(0x42, 0, 0, 0);
keybd_event(0x42, 0, 2, 0); keybd_event(0x12, 0, 2, 0); keybd_event(0x5B, 0, 2, 0);
}
}
"@
Add-Type -TypeDefinition $code
$gameRunning = $false
Write-Host "Monitoring for games... (Minimize this window)"
while($true) {
# This checks for any process running from a "common" Steam library folder
# Adjust "SteamLibrary" if yours is named differently
$activeGames = Get-Process | Where-Object { $_.Path -like "*SteamLibrary*" -or $_.Path -like "*steamapps*" } | Where-Object { $_.ProcessName -notmatch "steam|steamwebhelper|overlay" }
if ($activeGames -and -not $gameRunning) {
Write-Host "Game detected: $($activeGames[0].ProcessName). Enabling HDR..."
[Keyboard]::ToggleHDR()
$gameRunning = $true
}
elseif (-not $activeGames -and $gameRunning) {
Write-Host "No games detected. Disabling HDR..."
[Keyboard]::ToggleHDR()
$gameRunning = $false
}
Start-Sleep -Seconds 3 # Faster check (3 seconds)
}
Limitations
- Current detection scope is Steam game paths only.
- HDR uses toggle behavior (no direct state validation in this version).
- Custom Steam library names/locations may need path tweaks.
What I’ll improve next
- Add Epic/Battle.net/Xbox app detection
- Add safe state check to avoid accidental double-toggles
- Package into a cleaner tray-style utility
If you want the next version, I can share a multi-launcher edition with profile-based logic.
