Introducing lamco-rdp-tools: inspect an RDP server, then drive it

RDP finally has the command-line tools VNC always had: rdpsee inspects a server without logging in, and rdpdo drives the session, past where vncdotool stops.

GL
Greg Lamberson
· 6 min read

Here is something you could never do cleanly on RDP until today. Point one command at a whole subnet and read, for every RDP host on it, which security each one requires and what it negotiates, without logging in to a single one:

# Read every RDP host on a subnet, and fail CI if any allows weak security.
# No login. Nothing on the servers changes.
rdpsee scan 10.0.0.0/24 --ci --expect tls,nla

VNC users have had this kind of tooling for years. RDP users have not. Today I'm releasing the two small tools that close the gap: lamco-rdp-tools, from Lamco Development LLC. rdpsee inspects an RDP server without logging in, and rdpdo drives a session the way vncdotool drives VNC, taken well past it.

Product page: lamco.ai/products/lamco-rdp-tools. Source and releases: github.com/lamco-admin/lamco-rdp-tools.

The gap

VNC grew a mature command-line ecosystem a long time ago. vncdotool types and clicks and captures a screen from a script, vncsnapshot grabs a frame, and openQA does visual testing on top. RDP never grew the equivalent. The nearest things were Python projects that have either stopped (rdpy is unmaintained) or that aim at a different job entirely (PyRDP is built for man-in-the-middle and forensic capture, not desktop automation), plus a young headless client and the familiar workaround of driving FreeRDP inside a virtual X display, which is awkward to script and needs a display server running. So the people who automate or audit RDP have been gluing those together, or doing by hand what VNC users scripted a decade ago.

Two tools, not one

lamco-rdp-tools is two tools, and the split is the point. rdpsee observes and rdpdo acts. The line between them is not features, it is what each one does to the server: rdpsee only ever reads, so it is safe to point at production or at a host you are auditing, and rdpdo is the one that types and clicks and changes state. "What is this server?" is rdpsee. "Make this server do something" is rdpdo. Most real work uses both, in that order.

flowchart LR subgraph OBSERVE["rdpsee: observe, never changes the server"] direction TB S1["scan a subnet, no login"] --> S2["cert, id, report"] --> S3["shot: a screenshot"] end subgraph ACT["rdpdo: drive the session"] direction TB D1["log in, wait for the screen"] --> D2["type, click, match an image"] --> D3["assert, then JUnit for CI"] end OBSERVE ==> ACT

rdpsee: look before you touch

rdpsee inspects a server and never changes it. It works at three depths, from a probe that never opens a session up to a full login: a pre-authentication security scan across a whole subnet, the TLS certificate, a stable JA4-style fingerprint, the negotiated capabilities, and a screenshot, in five small commands (scan, cert, id, report, shot).

# Inspect one server's certificate and fingerprint, no login required.
rdpsee -s 192.168.1.10 cert
rdpsee -s 192.168.1.10 id

The one I keep coming back to is rdpsee scan. Reading a whole fleet's RDP security posture before authenticating, in a single command that fails your pipeline if any host allows weak security, is something neither the VNC world nor the RDP world had packaged cleanly. It turns "is anything on this network exposing RDP badly?" into one line you can put in CI.

rdpdo: drive the session

rdpdo takes a chain of commands and runs them in order on one connection. A single invocation can log in, wait for the screen to settle, type, click by matching an on-screen image, and assert the result. The breadth is wide: input, screen capture, visual matching, clipboard and file transfer, audio, display and multi-monitor, pixel checks, provisioning, calibration, scripting with record and replay, and baselines, about sixty commands across thirteen categories.

# Log in, wait for the desktop, check it against a baseline image,
# and write a JUnit report for CI.
rdpdo -s 192.168.1.10 -u user -p pass --junit results.xml \
  type "user" key tab type-password env:RDP_PASSWORD key enter \
  expect baselines/desktop.png 0.95 60

It started as the vncdotool for RDP, then went past it. Three of its tricks have no VNC equivalent at all: it can verify audio (RDP carries sound, and rdpdo can confirm a stream is playing or matches a reference), it produces real CI output (expect plus --junit and --fail-capture, so a visual check becomes a pass-or-fail test result), and it records a session and replays it as an editable script.

What it supersedes

These are our tools, so weigh the comparison accordingly, and here is the field represented fairly. On VNC, vncdotool and openQA are good, and you should use them. On RDP, the alternatives were the Python scatter above: rdpy stopped, PyRDP is right for forensics and man-in-the-middle but not automation, aardwolf is young, and FreeRDP inside a virtual display is a workaround rather than a tool. lamco-rdp-tools replaces that scatter with two static Rust binaries. rdpdo does what vncdotool does and adds visual matching, audio verification, recording, and CI output, and rdpsee does the inspection and reconnaissance no single RDP tool packaged before. No Python to install, no guest agent to deploy. If you need RDP man-in-the-middle or forensic capture, reach for PyRDP; for RDP automation, testing, provisioning, and inspection, this is the toolkit.

Built in the open

Both tools are written in Rust on IronRDP, Devolutions' open-source RDP stack, which is also where this team contributes the protocol work the tools depend on. They ship as two standalone binaries with no agent installed in the guest, they talk to any standards-compliant RDP server, and they are dual-licensed MIT OR Apache-2.0.

Where it works today

This is a first release, and I would rather name the edges than have you find them. The tools decode the common codecs, RemoteFX and, when the OpenH264 library is present at runtime, H.264 and AVC420, and rdpsee report tells you exactly what a given server negotiated. A couple of deeper graphics details wait on upstream IronRDP, and as that work lands the tools follow. None of that is guesswork: it is what is tested, against real servers, including our own Lamco RDP Server, which the same team scans and drives with these tools.

Try it

lamco-rdp-tools is available now from the GitHub release: download the signed binaries for your platform, verify the checksums, put them on your PATH, and run. The getting-started tutorial and the how-to guides ship with the repository, and the product page collects everything in one place. The protocol work underneath is real, and the tools are two commands you can run in a terminal. If you have ever wished RDP had what VNC users take for granted, this is it, twice over: the vncdotool it never had, and the inspector to go with it.

GL
Greg Lamberson

Founder of Lamco Development LLC. Building Linux infrastructure: a Wayland-native RDP server, a memory-safe UEFI bootloader, and open-source Rust and Kotlin libraries.

More about Greg ›