How to Check if Num Lock, Caps Lock, or Scroll Lock is On in Batch Script
The state of keyboard toggle keys (Num Lock, Caps Lock, and Scroll Lock) might seem trivial, but checking their status programmatically has real-world applications. Automated data entry scripts may require Num Lock to be on for numeric keypad input. Security-conscious login scripts might want to warn users if Caps Lock is enabled before they type a password. Kiosk setups may need Scroll Lock forced to a specific state for legacy terminal applications.
In this guide, we will explore how to detect and report the state of these toggle keys within a Batch Script, primarily using PowerShell integration since Batch alone cannot directly query keyboard hardware states.
The Challenge for Pure Batch
The Windows command prompt (cmd.exe) does not provide any native command to read the state of keyboard toggle keys. There is no if capslock==on syntax. The key states are maintained by the Windows keyboard driver and are only accessible through:
- The Windows API (
GetKeyStatefunction fromuser32.dll) - The .NET
System.Windows.Forms.Controlclass - The .NET
System.Console.CapsLockproperty (for Caps Lock and Num Lock only)
Since Batch scripts can embed PowerShell commands, we use PowerShell as the bridge to access these APIs.
Method 1: Using PowerShell's Console Class (Simplest)
The .NET [System.Console] class exposes CapsLock and NumberLock as static boolean properties. This is the simplest approach for those two keys.
@echo off
setlocal
echo Checking Keyboard Toggle Key States...
echo =======================================
:: Check Caps Lock
for /f %%A in ('powershell -noprofile -command "[System.Console]::CapsLock"') do set "caps=%%A"
:: Check Num Lock
for /f %%A in ('powershell -noprofile -command "[System.Console]::NumberLock"') do set "num=%%A"
echo Caps Lock: %caps%
echo Num Lock: %num%
if /i "%caps%" == "True" (
echo [WARNING] Caps Lock is ON!
)
pause
Limitation: No Scroll Lock
The [System.Console] class does not expose a ScrollLock property. To check all three keys including Scroll Lock, we need the Windows API approach (Method 2).
Method 2: Using the GetKeyState Windows API (Complete)
The GetKeyState function from user32.dll returns the state of any virtual key. For toggle keys, if the low-order bit of the return value is set (i.e., the value is odd), the key is toggled ON.
The virtual key codes are:
- Caps Lock:
0x14(20 decimal) - Num Lock:
0x90(144 decimal) - Scroll Lock:
0x91(145 decimal)
@echo off
setlocal
echo Reading Toggle Key States via Windows API...
echo =============================================
echo.
:: Use PowerShell to call GetKeyState for all three keys
for /f "tokens=1,2,3" %%A in ('powershell -noprofile -command ^
"Add-Type -MemberDefinition '[DllImport(\"user32.dll\")] public static extern short GetKeyState(int n);' -Name 'K' -Namespace 'W';" ^
"$c = [W.K]::GetKeyState(0x14) -band 1;" ^
"$n = [W.K]::GetKeyState(0x90) -band 1;" ^
"$s = [W.K]::GetKeyState(0x91) -band 1;" ^
"Write-Host $c $n $s"') do (
set "caps_state=%%A"
set "num_state=%%B"
set "scroll_state=%%C"
)
:: Convert 0/1 to human-readable ON/OFF
if "%caps_state%" == "1" (set "caps_label=ON") else (set "caps_label=OFF")
if "%num_state%" == "1" (set "num_label=ON") else (set "num_label=OFF")
if "%scroll_state%" == "1" (set "scroll_label=ON") else (set "scroll_label=OFF")
echo Caps Lock: %caps_label%
echo Num Lock: %num_label%
echo Scroll Lock: %scroll_label%
pause
How -band 1 Works
The GetKeyState function returns a short (16-bit integer). For toggle keys:
- If the lowest bit is
1, the key is currently toggled ON. - If the lowest bit is
0, the key is toggled OFF.
The -band 1 operation (bitwise AND with 1) isolates this lowest bit, giving us a clean 0 or 1 result.
Method 3: Interactive Dashboard
For a live monitoring tool or a pre-login check script, here is an interactive version that continuously displays the toggle key states.
@echo off
title Keyboard Toggle Monitor
setlocal
:loop
cls
echo =============================================
echo KEYBOARD TOGGLE MONITOR
echo =============================================
echo.
echo Press any key to refresh. Press Q to quit.
echo.
for /f "tokens=1,2,3" %%A in ('powershell -noprofile -command ^
"Add-Type -MemberDefinition '[DllImport(\"user32.dll\")] public static extern short GetKeyState(int n);' -Name 'K' -Namespace 'W';" ^
"$c = [W.K]::GetKeyState(0x14) -band 1;" ^
"$n = [W.K]::GetKeyState(0x90) -band 1;" ^
"$s = [W.K]::GetKeyState(0x91) -band 1;" ^
"Write-Host $c $n $s"') do (
if "%%A" == "1" (echo [X] Caps Lock ON) else (echo [ ] Caps Lock OFF)
if "%%B" == "1" (echo [X] Num Lock ON) else (echo [ ] Num Lock OFF)
if "%%C" == "1" (echo [X] Scroll Lock ON) else (echo [ ] Scroll Lock OFF)
)
echo.
set "key="
set /p "key=Press Enter to refresh or Q to quit: "
if /i "%key%" == "Q" exit /b
goto loop
Practical Use Case: Caps Lock Warning Before Password Entry
One of the most common applications is warning the user if Caps Lock is enabled before they type a sensitive password.
@echo off
setlocal
:password_prompt
cls
echo =============================================
echo SECURE LOGIN
echo =============================================
echo.
:: Check Caps Lock state
for /f %%A in ('powershell -noprofile -command "[System.Console]::CapsLock"') do set "caps=%%A"
if /i "%caps%" == "True" (
echo **************************************************
echo * WARNING: CAPS LOCK IS ON! *
echo * Your password may be entered incorrectly. *
echo **************************************************
echo.
)
set /p "password=Enter your password: "
:: (Password validation logic would go here)
echo.
echo Login attempt processed.
pause
Practical Use Case: Ensuring Num Lock for Data Entry
For data entry kiosks where the numeric keypad is essential:
@echo off
setlocal
echo Checking Num Lock for data entry...
for /f %%A in ('powershell -noprofile -command "[System.Console]::NumberLock"') do set "num=%%A"
if /i "%num%" == "False" (
echo [WARNING] Num Lock is OFF.
echo Please press the Num Lock key before continuing.
echo.
pause
goto :eof
)
echo [OK] Num Lock is ON. Proceeding with data entry...
:: Launch data entry application
pause
Common Mistakes
The Wrong Way: Trying to Read Key State Natively
:: WRONG - Batch has no native key state detection
if capslock==on echo Warning
Output Concern:
There is no such syntax in Batch. The command interpreter will treat capslock as a literal string and the condition will never be true. You must use PowerShell or an external utility.
The Wrong Way: Using mode con to Check Keys
:: WRONG - mode con shows console dimensions, not keyboard state
mode con
The mode command configures console window properties (columns, lines, baud rate). It has no relationship to keyboard toggle states.
Alternative: Using a Compiled Helper
If PowerShell startup time is unacceptable (it adds approximately 300-500ms of overhead), you can write a tiny compiled executable in C that calls GetKeyState and prints the result. This utility would execute in under 10ms.
:: Example using a hypothetical small utility
keystate.exe capslock
if %errorlevel%==1 echo Caps Lock is ON
While building custom utilities is beyond the scope of Batch scripting, it is worth mentioning for performance-critical environments.
Best Practices
- Use
[System.Console]for Caps and Num Lock: It is the simplest PowerShell call and does not require compiling C# code at runtime. - Use
GetKeyStatefor Scroll Lock: Since the Console class does not expose Scroll Lock, the API approach is necessary for a complete check. - Warn, don't force: When Caps Lock is on during password entry, warn the user with a visible message rather than silently toggling the key. Users may have intentionally enabled it.
- Minimize PowerShell calls: Each
powershell -commandinvocation has startup overhead. Combine all three key checks into a single PowerShell call to avoid running the interpreter three times.
Conclusion
Checking the state of Num Lock, Caps Lock, and Scroll Lock in Batch Script requires bridging into the .NET framework or Windows API via embedded PowerShell commands. The [System.Console] class provides the quickest path for Caps Lock and Num Lock detection, while the GetKeyState API from user32.dll covers all three toggle keys comprehensively. These techniques enable practical applications like password entry warnings, data entry kiosk validation, and system state monitoring dashboards.