Skip to main content

Python web dashboard for reserving and launching Windows Remote Desktop machines.

Project description

Windows Remote Desktop Dashboard

Python-based browser dashboard for reserving shared Windows RDP machines and pushing per-IP firewall locks so only the reserver can connect.

Install

pip install windows-remote-desktop-dashboard
windows-remote-desktop-dashboard

Open http://127.0.0.1:8000 (the app binds to 0.0.0.0 so other laptops on your LAN can hit it via the host machine's IP).

Development

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

Features

  • Dark, screenshot-style dashboard with machine list, details pane, admin modal, and audit log.
  • SQLite persistence under %LOCALAPPDATA%\WindowsRemoteDesktopDashboard\data by default on Windows.
  • One active reservation per machine, auto-released on expiry.
  • Direct local mstsc.exe launch with a downloadable .rdp fallback.
  • Generated .rdp files default to clipboard, drives, USB, printers, smart cards, audio capture/playback, multi-monitor, dynamic resolution, keyboard hook, and font smoothing all enabled.
  • RDP Login button automatically reserves the machine for the dashboard user, then launches C:\Windows\System32\mstsc.exe.
  • Windows firewall lockdown is ON by default: when a machine is reserved, the target PC's port 3389 is restricted to the reserver's IP and an explicit Block-Other-RDP rule is pushed so native mstsc.exe from anyone else is dropped at the network layer.
  • Verify lock button per machine that returns the actual rule state from the target host.
  • Background quser /server:<host> session checks that never block the page.
  • Admin PIN gate with single browser-session unlock and bulk delete/release/refresh controls.
  • Admin modal split into Settings, Inventory, and Manage Machines tabs.
  • Domain dropdown limited to EU and AP; any legacy FU rows are migrated to EU on startup.
  • Aggressive cache busting for static assets (custom static handler that returns Cache-Control: no-store and a per-process BUILD_ID query string).

Defaults That Match A Locked-Down Setup

Setting Default Override env var
Admin PIN admin ADMIN_PIN
Bind host 0.0.0.0 RDD_HOST
Browser launch host 127.0.0.1 RDD_BROWSER_HOST
Port 8000 RDD_PORT
Data dir %LOCALAPPDATA%\WindowsRemoteDesktopDashboard\data RDD_DATA_DIR
Default domain EU RDP_DOMAIN
Firewall lock ON RDD_ENFORCE_WINDOWS_FIREWALL=0 to disable at startup
Background session refresh ON RDD_AUTO_REFRESH_SESSIONS=0 to disable
Session refresh interval 30s RDD_SESSION_REFRESH_SECONDS
Firewall PowerShell timeout 20s RDD_FIREWALL_TIMEOUT_SECONDS
Auto-open browser yes RDD_OPEN_BROWSER=0 to disable

You can also toggle the firewall lock at runtime from Admin → Settings → RDP lock ON/OFF. The setting is persisted in SQLite.

Diagnosing "Why Can I Still RDP Directly?"

If you reserve a machine and you (or someone else) can still RDP into it natively, one of these is true:

  1. You are the reserver. The firewall rule allows the reserver's IP through. Test from a DIFFERENT IP than the one shown in the "Locked by ... · <IP>" pill on the dashboard.
  2. Firewall step failed silently — in 0.4.0 it does NOT silently fail anymore. The dashboard now records the firewall status with every reservation and pops up a warning when the lock could not be applied (no WinRM, no admin rights, no IP, etc.). The "Locked by" pill shows the allowed IP, and an amber chip shows the failure reason if it failed.
  3. You ran the dashboard from localhost — in 0.4.0 the server now falls back to its own outbound LAN IP toward the target instead of trying to write 127.0.0.1 into the firewall rule.

Use Admin → Manage Machines → Diagnose on the target to get a structured report: ping, WinRM reachability, dashboard's outbound IP toward the target, and the actual firewall rule state. Use Verify lock to confirm the lock is currently active.

How The Native-RDP Block Works

When RDP lock is ON the dashboard runs the following on the target machine over WinRM, every time a reservation is created:

  1. Tighten every inbound Remote Desktop rule's RemoteAddress filter to the reserver's client IP.
  2. Add RDD-Block-Other-RDP (Block, TCP 3389, RemoteAddress=Any) so anything not matching the reserver IP is dropped.
  3. Add RDD-Block-Other-RDP-Allow (Allow, TCP 3389, RemoteAddress=) so the reserver still gets in.

When the reservation is revoked/released/deleted those two RDD-* rules are removed and the Remote Desktop rules are restored to RemoteAddress=Any.

Requirements for this to actually block native RDP:

  • The dashboard server is Windows and runs as a user that can Invoke-Command on the target PCs (typically domain admin on the targets or WinRM with Enable-PSRemoting).
  • WinRM (winrm quickconfig) is enabled on every target PC.
  • Users open the dashboard with the server's LAN hostname/IP, not localhost, so the dashboard can read their real client IP and not 127.0.0.1.

Use Admin → Manage Machines → Verify lock to check a specific target. If WinRM is misconfigured the dashboard will report the exact PowerShell error.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

windows_remote_desktop_dashboard-0.4.0.tar.gz (24.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file windows_remote_desktop_dashboard-0.4.0.tar.gz.

File metadata

File hashes

Hashes for windows_remote_desktop_dashboard-0.4.0.tar.gz
Algorithm Hash digest
SHA256 b8a32da9394fb2d621c6e330e53e5ed0ad0ce684ebe586e2e9964063ac59c3a4
MD5 192c0dfcce577a77b562ec6b85c74780
BLAKE2b-256 28916b7f289805b5f35d6573af6bbc1152d78a183d9f16dd07e4a9103fcd5596

See more details on using hashes here.

File details

Details for the file windows_remote_desktop_dashboard-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for windows_remote_desktop_dashboard-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a479f70f6411fc58862764caa9e52a6ba5bcb151b46bd96d223111028d7f8e97
MD5 943c435d7a96b6aa564269089d33cae7
BLAKE2b-256 fa17e73aa2a6646036a86cad369d7d07154303548436451aabdc10b423baf490

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page