v0.3.2 — first working release
wtf-rdp v0.3.2 — first working release
Rescue the RDP session Windows would make you destroy.
wtf-rdp is a Windows RDP session-rescue CLI (rdp) in the wtf-windows family, built on the DazzleCMD pattern. It detects and non-destructively recovers RDP/console sessions wedged or blocked by Local Session Manager (LSM) — the "You're unable to sign in because you're already signed in to another session that is blocked" failure that otherwise forces you to sign the session out and lose your work.
This is the first release that works from a plain
pip install— 0.3.0/0.3.1 shipped the tool scripts but not their manifests, so the installed CLI found no tools (see the fix note below). If you tried an earlier version, upgrade:pip install --upgrade wtf-rdp.
The problem it solves
An ungraceful mstsc disconnect can leave your session flagged "blocked by Local Session Manager." From then on Windows refuses every sign-in (RDP and including the physical console) and the only button it offers is the one that signs the session out and throws away everything running in it. The block counter climbs and never expires, and on client Windows (a single interactive session) you can't even open a second session to fix it. Remote fixes (tscon, restarting TermService, rwinsta) are typically blocked by remote-UAC token filtering. The usual "recovery" destroys exactly the work you were trying to save.
How it works
- The failure — a dirty RDP disconnect leaves the session in a corrupted "wedge"; LSM marks it blocked and refuses new sign-ins.
- Detection — a wedge looks, to a naive check, like a healthy machine at its login screen, so wtf-rdp does not act on "a session is disconnected." It watches for the real signature: a console session stuck connecting, corroborated by the LSM transition-failure event a dirty disconnect emits, persisting past a short confirm window. Normal idle disconnects never trigger it.
- Recovery — it reconnects the stranded session to the console with
tsconand then locks it, so your running work survives and the box is never left with an open desktop. - Where it runs — a small PowerShell watchdog hosted by NSSM as a
LocalSystemservice. Because it runs asSYSTEMit inherently holds theSeTcbPrivilegethattsconneeds, so recovery works with no change to the machine's admin/token model (noLocalAccountTokenFilterPolicy, no enabled built-in Administrator), and it can act autonomously with nobody logged in — which is the point, since the wedge is exactly what locks you out.
The sessfix kit — seven tools
Install/operate wtf-rdp on the RDP host (the machine that wedges — the one you connect into). The machine you connect from just uses mstsc as usual.
| Tool | What it does |
|---|---|
rdp status |
Watchdog service state + recent rescues + live session table |
rdp query |
Enumerate sessions; flag Stranded / WedgeSignal candidates (-Json) |
rdp install |
Deploy + start the LocalSystem watchdog (downloads a checksum-verified NSSM) |
rdp recover |
Manual one-shot reconnect + lock now; self-elevates to SYSTEM |
rdp logs |
View the watchdog log (-Tail / -Follow / -Full) |
rdp config |
Show / change poll interval, wedge-confirm window, target user |
rdp uninstall |
Stop + remove the service (-Purge also deletes the install dir) |
Every tool answers -h / -help / --help / /?.
Installation
pip install wtf-rdpOn externally-managed Python (PEP 668), use a venv or pipx install wtf-rdp. Requires Windows and Python 3.10+.
Getting started
In an elevated PowerShell on the RDP host:
# Deploy + start the watchdog, scoped to just your account so it only ever
# acts on your session. (Omit -TargetUser to rescue any stranded session.)
rdp install -TargetUser $env:USERNAME
# Confirm it's Running as SYSTEM and see the live session table
rdp statusThat's the whole setup — it now runs across reboots and will reconnect + lock your session if it wedges. Day to day:
rdp query # flag stranded / wedge candidates
rdp logs -Follow # watch the watchdog live
rdp recover # force a reconnect + lock right now
rdp config -PollIntervalSec 10 # tune how often it checks (restarts the service)What's New / Fixed in v0.3.2
Fixed: the installed wheel now finds its tools (#1)
The per-tool manifests are named .wtf-rdp.json (leading dot), and setuptools' * glob skips dotfiles — so package-data's tools/**/* shipped every .ps1 but silently dropped every manifest that dispatches them. The result: pip install wtf-rdp → "No tools found" and rdp install reported an invalid choice, even though the source/editable checkout worked. Fixed by packaging the dotfile manifests explicitly, with a regression test to guard it. Verified end to end: rebuilt the wheel, installed it into a clean venv, and rdp list reports all 7 tools.
Everything from 0.3.0 (the query/logs/config tools, universal -h, the rdp -h epilog, checksum-verified NSSM pinned by default) and 0.3.1 (manual workflow_dispatch on the release workflow) is included — this is the first build where it's actually usable after pip install.
Version History (0.3.x)
| Version | Key Change |
|---|---|
| v0.3.2 | Current — first working wheel: package the .wtf-rdp.json tool manifests |
| v0.3.1 | First public release + manual workflow_dispatch (wheel was missing tool manifests) |
| v0.3.0 | sessfix query/logs/config, universal -h, verified NSSM pin (source-only) |
| v0.2.0 | install / recover / uninstall + lock-after-rescue; shared session module |
| v0.1.0 | Aggregator scaffold (rdp) + sessfix status; validated watchdog |
Platform Support
| Platform | Status |
|---|---|
| Windows 11 | Tested |
| Windows 10 | Expected to work |
The rdp CLI is Python and installs anywhere, but the sessfix tools are Windows-only (they no-op / warn off-Windows).
Requirements
- Python 3.10+
- Windows (for the
sessfixsession-rescue tools) - Administrator (elevated shell) for
install/recover/uninstall/configwrites