Skip to main content

Remote Desktop Dashboard — monitor machines and connect via Microsoft Windows App

Project description

Remote Desktop Dashboard

A LAN-only, browser-based dashboard for monitoring and connecting to a fleet of Windows benches over RDP. Operators see who is using each machine, reserve one with a single click, and the dashboard hands their browser an rdp:// URI that opens the Remote Desktop login screen directly — no file download, no extra modal. A small PowerShell agent on each bench locally enforces who is allowed to RDP — including blocking local administrators bypassing the "Remote Desktop Users" group, via per-IP firewall rules.

What's new in 2.14

  • One-click RDP launch with native mstsc.exe — the way it was meant to work. Click Connect → mstsc opens directly to the RDP login screen, no file in your Downloads folder. Requires running the new per-operator installer (install-rdp-handler.ps1) once on each PC — no admin elevation, HKCU only. See Share -> One-click RDP launch in the dashboard for the download and instructions.
  • Graceful fallback when an operator hasn't installed the handler yet: the dashboard detects that nothing opened, automatically triggers the universal .rdp download so the launch still works, and surfaces a dismissible card explaining how to switch to the no-download flow.
  • Diagnose modal redesigned — colour-coded summary pills, every check shown even when it passes (no more "verdict-only" mystery), "Copy report" button for pasting into a support email, "Run again" button without closing.
  • Admin PIN moved off the URL for two more endpoints — push install command and agent diagnostics now use X-Admin-PIN header, so the PIN never lands in server access logs.
  • WebSocket reconnect no longer leaks ping timers. Long-uptime tabs could end up sending pings for every dead socket they'd ever opened.
  • Native, native, native. The handler installer explicitly points rdp:// at %WINDIR%\System32\mstsc.exe — no Windows App, no msrdc, no Microsoft Store dependency.

What's new in 2.13

  • Direct RDP launch. Click Connect → Windows opens the RDP login screen immediately. No more .rdp file in the Downloads folder, no more "popup that closes before any interaction" — both were artefacts of the old browser-download flow. (Note: in 2.13 this only worked if the operator had Microsoft Windows App / msrdc installed. From 2.14, you can run the per-operator installer to make it work with native mstsc.exe too.)
  • Lock acquisition is race-safe. Two operators clicking Connect on the same bench at the exact same instant can no longer both end up with a reservation; the loser gets a friendly 409.
  • Admin PIN moved to the X-Admin-PIN header. Old ?admin_pin= query strings are still accepted for compatibility, but the UI now sends the PIN as a header so it never lands in proxy / browser / SIEM access logs.
  • /health no longer leaks filesystem paths to anonymous LAN callers. Admins still see them (pass X-Admin-PIN).
  • Legacy /machines/{name}/status is no longer open by default. Requires either RDD_AGENT_API_KEY or RDD_BENCH_AGENT_TOKEN.
  • admin.env template default flipped: RDD_BENCH_AGENT_KICK_OTHER_SESSIONS=false. Auto-kicking on every lock contradicted the documented design.
  • Constant-time secret comparison (hmac.compare_digest) for the admin PIN, bench-agent token and legacy API key.
  • 127.0.0.1 local launcher off by default — the new rdp:// flow removes the need for it. Enable with RDD_LOCAL_LAUNCHER_ENABLED=true.

Quick start (server-side, one machine on the LAN)

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

Then open http://localhost:8080/ in a browser on the same machine.

Default port is 8080. The first time you start it, it writes %LOCALAPPDATA%\RemoteDesktopDashboard\admin.env with sensible defaults.

Keep the dashboard running automatically

In an elevated PowerShell on the server PC:

remote-desktop-dashboard install-autostart

This registers a Windows Scheduled Task (RemoteDesktopDashboard) that fires every 5 minutes. The dashboard's single-instance lock makes the duplicate fires no-op while it's already running, but if the terminal is closed, the server crashes, or the PC reboots, the scheduler relaunches it automatically within 5 minutes. It runs windowless (no flashing console) via pythonw.exe.

Check status / inspect / remove:

remote-desktop-dashboard service-status
remote-desktop-dashboard uninstall-autostart

How users on OTHER PCs open the dashboard

The dashboard is just a web server on TCP 8080. Anyone on the same LAN who can reach the server PC can use it — no install on their machine.

  1. On the server PC (the one running the dashboard), allow inbound TCP 8080 through Windows Firewall (run in an elevated PowerShell):

    New-NetFirewallRule -DisplayName "Remote Desktop Dashboard" `
      -Direction Inbound -Protocol TCP -LocalPort 8080 `
      -Action Allow -Profile Any
    
  2. Find the server PC's LAN IP:

    ipconfig | Select-String IPv4
    

    Or click the share icon in the top right of the dashboard — it shows every LAN URL the server is reachable on, with one-click copy.

  3. From any other PC on the LAN, open http://<server-pc-ip>:8080/ in a browser. That's it.

There is no login wall — anyone who can reach this URL can use the dashboard. Admin-only actions (push install, force release, kick others, emergency restore RDP, manage machines, server settings) are gated behind the Admin PIN (see below).

How the RDP launch actually works (2.13+)

When an operator clicks Connect on their PC, the dashboard:

  1. Reserves the bench under their name (race-safe atomic UPDATE — two simultaneous clicks can no longer both "win").
  2. Hands their browser an rdp:// URI (e.g. rdp://full%20address=s:atc05.lab:3389&redirectclipboard=i:1&...).
  3. The browser asks the OS to open that URI; Windows routes it directly to mstsc.exe (the built-in Remote Desktop client). The RDP login screen opens immediately — no .rdp file is downloaded, no extra modal pops up on the dashboard, and the dashboard tab stays put for the heartbeat / lock loop.
  4. The first time the user clicks Connect, the browser may show a one-time "Open Remote Desktop Connection?" confirmation. Ticking "Always allow" makes future launches frictionless.

The URI sets the same defaults the .rdp file would have:

  • Clipboard redirection (redirectclipboard=i:1)
  • Audio playback on the operator's PC (audiomode=i:0)
  • Smartcard redirection
  • Network auto-detect + dynamic bandwidth
  • Auto full-screen
  • Authentication level 2 (warn but allow if cert mismatch)

A traditional .rdp file fallback is still served at /api/v1/machines/<name>/session.rdp for operators who want a desktop shortcut. It now requires ?operator=<your-name> and only succeeds for the operator who currently owns the lock (or an admin via X-Admin-PIN), so a hand-crafted URL can't bypass a reservation.

Set RDD_PREFERRED_RDP_CLIENT=windows_app in admin.env if you want to opt-in to the new Microsoft Windows App on operator PCs that have it.

External RDP sessions (2.12+)

The bench agent reports every session it sees on the bench, not just dashboard-initiated ones. If someone bypasses the dashboard and RDPs directly, they show up in the machine's "Logged-in users" cell on the dashboard within a few seconds, even when the bench is reserved by someone else. Admins can hit Force release + Kick others to boot them.


HTTPS (remove the “Not secure” warning)

By default the dashboard runs over plain HTTP, so Chrome/Edge show a Not secure badge in the address bar. That's harmless on a trusted LAN but ugly. To get a real green lock instead:

  1. Start the dashboard with HTTPS:

    remote-desktop-dashboard --https
    

    On first start it generates a self-signed certificate into the data folder (dashboard-cert.pem + dashboard-key.pem) covering localhost, 127.0.0.1, the machine hostname, and all detected LAN IPs. The same cert is reused on every subsequent start, so clients only install it once.

  2. To make it permanent across reboots, set RDD_HTTPS_ENABLED=true in admin.env (next to RDD_ADMIN_PIN) and re-run remote-desktop-dashboard install-autostart.

  3. On each client PC (one-time):

    • Open the dashboard, click the share icon, scroll to "Remove the Not secure warning" and click Download certificate.
    • Double-click the downloaded .crt file.
    • Install CertificateLocal MachinePlace all certificates in the following storeTrusted Root Certification Authorities → Finish.
    • Close and reopen the browser. The lock icon turns green.

If you already have your own real cert (e.g. issued by an internal CA), point at it instead:

remote-desktop-dashboard --https --cert C:\path\to\cert.pem --key C:\path\to\key.pem

Why a self-signed cert is the only LAN-friendly option

Public CAs (Let's Encrypt, ZeroSSL, …) cannot issue certificates for LAN names like 192.168.1.50 or WORKSTATION-PC. Until you install the dashboard's cert as a trusted root on each client, the browser shows "Your connection is not private — NET::ERR_CERT_AUTHORITY_INVALID". After install it shows a normal green lock.

Desktop shortcut for users

The Share modal also offers a one-click Download desktop shortcut. This is a tiny HTML file users can drop on their desktop and double-click to open the dashboard — it auto-redirects to the right URL/scheme.

Earlier versions (≤ 2.11.0) used a Windows .url Internet Shortcut, which Chrome/Edge SmartScreen flagged as a harmful download. From 2.11.1 the shortcut is a plain HTML file (same UX, no warning).


Roles

There are two roles, enforced server-side:

Role What they can do How they are recognized
Operator View status, connect, release their own lock, view audit log Anyone who opens the dashboard URL
Admin All of the above plus push-install agent, force release, kick others, emergency-restore RDP, manage machines, edit server settings Knows the Admin PIN

Most users only ever need to be operators. They just open the dashboard URL, type their name and RDP credentials once (the server remembers them per-name across PCs), and connect.

Admin PIN

The Admin PIN is a single, server-wide secret set by whoever installed the dashboard, in %LOCALAPPDATA%\RemoteDesktopDashboard\admin.env:

RDD_ADMIN_PIN=pick-something-only-you-know

Restart the dashboard after changing it.

The PIN is not shown anywhere in the UI for non-admins. To use it, click the lock icon ("Admin") at the top right and type the PIN. The UI remembers it for the current browser tab (cleared on close) and unlocks admin-only actions. Click the icon again to sign out.


Bench agent (recommended)

For each bench you want to lock, push-install the PowerShell agent from the dashboard:

  1. In admin.env on the server set RDD_BENCH_AGENT_TOKEN=<long-random-string> and restart the dashboard. (This is the shared secret the agents use to authenticate to the dashboard.)
  2. Make sure the dashboard's monitor service account is a local admin on every bench.
  3. Open the dashboard, sign in as admin, open Settings, scroll to Bench Agent, and click Push install next to each bench.

The agent:

  • Manages the local "Remote Desktop Users" group based on the current dashboard lock.
  • Manages a local Windows Firewall rule on TCP 3389 so that, when a bench is locked, only the lock owner's IP can RDP — this blocks even local administrators from RDPing directly (which would otherwise bypass the group check).
  • Kicks unauthorized RDP sessions if they sneak in.
  • Heartbeats back to the dashboard every few seconds.

Emergency: restore native RDP on a bench

If something goes wrong with the firewall rule and you can't get back into a bench, the admin can hit Restore native RDP in the dashboard (detail panel on the right of the Status tab). This tells the agent to:

  1. Remove the custom firewall lock rule.
  2. Re-enable the built-in Windows "Remote Desktop" rules.
  3. Release the dashboard lock.

If the agent is offline, the dashboard also shows a PowerShell snippet you can paste on the bench from an elevated shell. It does the same three things directly.


Configuration (admin.env)

On Windows, %LOCALAPPDATA%\RemoteDesktopDashboard\admin.env. The most relevant keys:

Key Purpose Default
RDD_ADMIN_PIN The Admin PIN gating admin actions unset
RDD_BENCH_AGENT_TOKEN Shared secret the bench agents use to authenticate unset
RDD_BENCH_AGENT_FIREWALL_LOCK If true (default), the agent enforces the per-IP firewall lock true
RDD_MONITOR_DOMAIN/USERNAME/PASSWORD Service account used to poll sessions on each bench unset

Most users never have to edit this file. The dashboard's Settings drawer edits the monitor account fields directly; the file is updated for you.


Troubleshooting

  • Machines show red even though they're online. The dashboard now treats a heartbeating bench agent as proof the machine is online. If you've installed the agent and the dot is still red, open the agent's Diagnose button in Settings → Bench Agent; the most common cause is the agent failed to start (scheduled task RDD-Bench-Agent last-result != 0).

  • Chained RDP still works (RDPing into Bench A, then RDPing from Bench A to Bench B). Make sure the bench agent on Bench B is running v2.1.0 or later (Agent v2.1.0 online in Inventory). The firewall rule is what blocks this; if it's not applied, see Diagnose.

  • "Invalid admin PIN." The PIN is whatever is on the right-hand side of RDD_ADMIN_PIN= in admin.env on the server, with no surrounding quotes and no leading/trailing spaces.

  • I locked myself out of a bench. Click the Admin lock icon → sign in → open the bench's detail panel → Restore native RDP. If the agent is offline, paste the shown PowerShell on the bench.


Development

git clone <this repo>
cd remote_desktop_dashboard
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
pytest

The PowerShell agent and installer scripts ship in src/remote_desktop_dashboard/data/. They are parser-checked on every test run (tests/test_bench_agent_scripts.py) — silent agent crashes from PowerShell parse errors used to be a recurring problem, so that test gates every release.

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

remote_desktop_dashboard-2.15.0.tar.gz (139.6 kB view details)

Uploaded Source

Built Distribution

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

remote_desktop_dashboard-2.15.0-py3-none-any.whl (165.1 kB view details)

Uploaded Python 3

File details

Details for the file remote_desktop_dashboard-2.15.0.tar.gz.

File metadata

File hashes

Hashes for remote_desktop_dashboard-2.15.0.tar.gz
Algorithm Hash digest
SHA256 0eb5f03fc4c87e04d129ee5dec03f01b76b8f2a115c74c450afd71ba8850bf1a
MD5 21c36dab7afcf03cda817bfa5dd0f73a
BLAKE2b-256 f117b7e6d11864cf1112dd362c903fa36fad0662952eb048f20623425c9b2f87

See more details on using hashes here.

File details

Details for the file remote_desktop_dashboard-2.15.0-py3-none-any.whl.

File metadata

File hashes

Hashes for remote_desktop_dashboard-2.15.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0ebea696bf9cd37589d0584228d972a3081dd5b6a4f7408d88648559d9f51e32
MD5 c2b0a9c66fbc39aa232ef3bbd22844f0
BLAKE2b-256 d442ecf5558c2b019304767a955d5c0a7fb362327243e28d338bc39933dbca4a

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