A dual-mode Windows keyboard & mouse locker powered by a Batch/PowerShell polyglot.
One
.batdouble-click. Zero dependencies. Your keyboard and mouse, completely frozen — then automatically restored.
This tool locks ALL keyboard and mouse input at the Windows API level. If used incorrectly, you WILL lose control of your machine until the timer expires or the system is rebooted.
- You cannot unlock early using the keyboard or mouse — they are hardware-blocked.
- Do not use on a remote desktop / RDP session you rely on; you could permanently lock yourself out of a remote machine.
- Do not run on a system where you cannot physically power-cycle the machine as a last resort.
- Do not run inside a Virtual Machine when testing unless you are confident in your VM's forced-stop controls.
- The author and contributors accept zero liability for lost work, locked sessions, or any other damage. Use entirely at your own risk.
Emergency Recovery: Pressing Ctrl + Alt + Delete is handled at the Windows kernel level and is not blocked by BlockInput. It will open the Windows security screen, from which you can launch Task Manager to terminate the script. A hard power-off or forced VM shutdown is the last resort.
Time-out provides two .bat scripts that temporarily lock all keyboard and mouse input on a Windows machine for a configurable number of seconds. The project is a practical study in advanced scripting techniques: both scripts call the BlockInput function from Windows' user32.dll via a PowerShell P/Invoke bridge, but each script uses a different architectural pattern to get there.
lock_v3_polyglot.bat is a polyglot — a single file that is simultaneously valid syntax in two different languages: Windows Batch (CMD) and PowerShell. This is achieved through a clever abuse of each interpreter's parsing rules:
<# :
@echo off
...
| Interpreter | How it reads <# : |
|---|---|
| CMD / Batch | Sees : as a label definition. The <# characters are discarded. Execution continues with @echo off. |
| PowerShell | Sees <# as the opening of a block comment. Everything up to the matching #> is invisible to PS. |
This means the Batch section (UAC elevation logic, the bridge call) is hidden from PowerShell, and the PowerShell section (the BlockInput logic) is hidden from Batch. The exit /b command stops Batch before it ever reaches the PowerShell code; the #> tag terminates the block comment, activating the PS code below it.
The Batch engine then executes this one-liner to hand off to PowerShell:
powershell -command "iex (${%~f0} | out-string)" -- %*This tells PowerShell to read the entire file (%~f0) as a string and execute it with Invoke-Expression. The PowerShell engine runs it, sees its own block comment close at #>, and begins executing the real PS logic. No temporary file is ever written to disk.
Both scripts use net session >nul 2>&1 to probe for admin rights. This command fails with a non-zero %errorlevel% if the process is not elevated.
Polyglot script re-launches itself via PowerShell's Start-Process with the -Verb RunAs flag (triggers the Windows UAC prompt):
powershell -Command "Start-Process cmd.exe -ArgumentList '/c \"\"%~f0\" %*\"' -Verb RunAs"Generator script creates a temporary VBScript file (%temp%\getadmin.vbs) using the Shell.Application COM object and calls .ShellExecute with the "runas" verb:
echo Set UAC = CreateObject("Shell.Application") > "%temp%\getadmin.vbs"
echo UAC.ShellExecute "%~f0", "%*", "", "runas", 1 >> "%temp%\getadmin.vbs"The .vbs file is immediately deleted after the elevated process launches.
Once running as Administrator, both scripts load the BlockInput function from user32.dll using C#-style P/Invoke declarations via PowerShell's Add-Type:
$signature = '[DllImport("user32.dll")] public static extern bool BlockInput(bool fBlockIt);'
$API = Add-Type -MemberDefinition $signature -Name "Win32Utils" -Namespace "Win32" -PassThruBlockInput(true) sets a flag in the Windows input thread that causes it to discard all hardware events from the keyboard and HID mouse devices. BlockInput requires Administrator rights and returns $false if called without them — so without elevation, the lock simply never engages.
The lock duration counts down with a colored ASCII progress bar:
[########------------] 40% Remaining: 6 sec
Color changes dynamically: Green → Yellow (≤ 6 seconds) → Red (≤ 3 seconds).
The unlock call is wrapped in a try...finally block — the most important safety mechanism in the entire script:
try {
# countdown loop
} finally {
$API::BlockInput($false) # <-- GUARANTEED to run no matter what
}Because the call to BlockInput($false) sits in the finally block, it executes whether the countdown completed normally, threw an exception, or was interrupted. This is what makes the tool reversible by design.
The generator script writes the PowerShell logic to a temporary .ps1 file line-by-line using echo >> redirection, then launches it with:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%temp_ps%"%RANDOM% is appended to the filename (LockInputTask_%RANDOM%.ps1) to prevent race conditions if two instances are run simultaneously. The PS1 script contains a self-deletion command as its final instruction:
Remove-Item -Path $MyInvocation.MyCommand.Path -Force -ErrorAction SilentlyContinueThis ensures no temporary artifact persists in %TEMP% after execution.
- Dual architectural modes — choose between the elegant polyglot (memory-only) or the transparent generator (disk-based, easier to inspect and debug).
- Zero external dependencies — requires only Windows,
cmd.exe, andpowershell.exe, all of which ship with every modern version of Windows. - Hardware-level input blocking — uses
user32.dll::BlockInput, the same Win32 API used by kiosk and accessibility software. - Guaranteed automatic unlock — the
try...finallyfailsafe ensures the lock is always released when the timer expires, even if an exception occurs mid-countdown. - Configurable duration — pass any positive integer as a command-line argument to set the lock duration in seconds.
- Quiet / Silent mode — the
/quietflag suppresses all console output for scripted or scheduled use. - Colored progress bar — a live, color-coded ASCII progress bar provides clear visual feedback of remaining lock time.
- Auto self-elevation — both scripts detect insufficient privileges and re-launch themselves with a UAC prompt automatically.
- Self-cleaning — the generator script's temporary
.ps1file self-deletes; the polyglot never writes a file at all.
| Component | Role |
|---|---|
| Windows Batch (CMD) | Entry point, argument parsing, privilege detection, auto-elevation bootstrap |
| PowerShell | Execution engine for the core locking logic |
Win32 API (user32.dll) |
Provides the BlockInput function that intercepts hardware input |
C# P/Invoke (inline, via Add-Type) |
Used inside PowerShell to declare and call the unmanaged BlockInput function |
| VBScript (generator only) | Temporary UAC elevation shim; created and deleted at runtime |
BlockInput is a privileged Win32 API call. Calling it from a standard (non-elevated) process returns $false and the lock does not engage. Both scripts check for elevation at startup and trigger a UAC dialog automatically if needed.
You must click "Yes" on the UAC prompt to allow the script to function.
If UAC is disabled on the target system, the script must be run explicitly from an Administrator-privileged cmd.exe session:
:: Right-click cmd.exe → "Run as administrator", then:
lock_v3_polyglot.bat 30- Windows 7 or later (Windows 10/11 recommended)
- PowerShell 3.0 or later (included with Windows 8+)
- Administrator access on the machine
- Download
lock_v3_polyglot.batorlock_v3_generator.batfrom thesrc/directory. - Double-click the file. A UAC prompt will appear — click Yes.
- The input will lock for the default 10 seconds, then automatically restore.
:: Lock for 10 seconds (default)
lock_v3_polyglot.bat
:: Lock for 30 seconds
lock_v3_polyglot.bat 30
:: Lock for 60 seconds with no console output (silent mode)
lock_v3_polyglot.bat 60 /quiet
:: Same usage applies to the generator script
lock_v3_generator.bat 45
lock_v3_generator.bat 20 /quietTip: To run from an already-elevated prompt without a UAC popup, open
cmd.exeas Administrator and call the script directly.
| Feature | lock_v3_polyglot.bat |
lock_v3_generator.bat |
|---|---|---|
| Disk footprint | Memory-only — no files written | Writes a temp .ps1, then self-deletes |
| Elevation method | PowerShell Start-Process -Verb RunAs |
VBScript Shell.Application COM + runas |
| Architectural complexity | High — dual-language polyglot | Low — standard Batch logic |
| Antivirus profile | Stealthy — no file drop | May flag as "suspicious script drop" |
| Debuggability | Hard — code is inline and memory-only | Easy — pause before execution to inspect the generated .ps1 |
| Best for | Deployment; end-user distribution | Learning; development; auditing the generated logic |
| Scenario | Recommended Usage |
|---|---|
| Screen cleaning | Run with default 10 seconds to safely wipe a touchscreen or keyboard without accidental input |
| Child-proofing / AFK | Run with 60–120 seconds when stepping away from a machine a child has access to |
| Kiosk setup | Use with /quiet and a scheduled task to lock the station between interactions |
| Focus / Pomodoro pause | Run for 300 seconds to enforce a hands-off break from a work session |
| Scripted automation | Combine with /quiet and a task scheduler trigger to lock input during a sensitive automated process |
| Learning Win32 P/Invoke | Use the generator script as a live code-generation teaching tool |
The following are ideas for future development. None of these are currently implemented.
- Graphical countdown overlay (WPF/WinForms) displayed on top of the lock screen
- Optional unlock PIN or passphrase delivered via a system tray prompt
- Exclusion of specific keys (e.g., Ctrl+Alt+Delete awareness note for users)
- A dedicated installer / uninstaller script
- Scheduled-task integration helper script
- Support for locking only the mouse while leaving the keyboard active (requires a low-level hook approach via
SetWindowsHookEx, distinct fromBlockInput) - Packaging as a signed executable to reduce antivirus false positives
Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request — it contains critical safety requirements for testing polyglot scripts.
Distributed under the MIT License. See LICENSE for full text.