DrainCtl monitors every session host in your RDS farm — drain mode changes, active sessions, CPU, memory, input delay. One service, one dashboard, instant alerts. The change, who made it, and how long ago.
irm https://lissconsulting.github.io/LISSTech.DrainCtl/install.ps1 | iex
You've got a script. It polls every 5 minutes. Maybe it emails you. But it doesn't know who changed it, it can't attribute events to a user account, and the last thing you need is another fragile cron job to maintain.
Log into each server. Run chglogon /query. Check 8 hosts. Repeat. You're always the last to know — and there's no record of how long the server was drained or who was responsible.
PRTG, Zabbix, and your RMM don't understand RDSH drain semantics. They'll alert on everything or nothing, and you'll spend more time tuning thresholds than managing your farm.
chglogon /drain, the service knows. No polling
delay — Windows notifies DrainCtl directly through the kernel.
evtspike learns a per-channel baseline across 54 Windows event logs.
Catches what fixed thresholds miss — without false-positive noise.
Run the MSI on your dashboard server with the interactive wizard, or use PowerShell for silent RMM deployment.
irm https://lissconsulting.github.io/LISSTech.DrainCtl/install.ps1 | iex
Point your internal DNS at the dashboard host. Every session host finds it on its own — no scripts, no URLs pushed to machines.
_drainctl._tcp.contoso.com → your-dashboard-host:49470
Agents self-register. The dashboard shows every server. Drain changes alert in under a second. Edit thresholds and notifications once in the UI — the dashboard is authoritative, every agent pulls the same config on reload.
One DNS SRV record. Every agent finds the dashboard on its own. No scripts, no per-machine config, no manual URLs.
_drainctl._tcp.contoso.com
Auto TLS on first start. Self-signed cert, or bring your own. Certificate pinning. HSTS. Private key locked to SYSTEM.
SMTP email with HTML templates and natural-language subjects. Webhook and ntfy.sh too. Manage all targets from the dashboard with per-target triggers.
CPU, memory, input delay, disk I/O, and optional RemoteFX — collected via PDH on the configured sample interval. Threshold alerts fire before users complain.
Add-, Get-, Remove-RDSHDrainNotificationTarget.
Full multi-target control from PowerShell.
Interactive wizard or silent deploy. INSTALL_MODE=dashboard,
DASHBOARD_URL=..., ENABLE_PERF=1 — configure machine-owned settings from the command line.
Upgrades skip config dialogs and preserve existing settings.
drainctl dashboard enable, add one DNS SRV record, done. Agents discover and
register themselves.
Auto TLS, Kerberos SSO or credential login, certificate pinning, HSTS. Session-based auth with 8-hour timeout.
Real-time updates via Server-Sent Events. LOAD, Health Indicators, Session, and optional RemoteFX panels query retained SQLite telemetry; every Server Detail has a durable host LOAD chart with shared zoom presets.
Notification targets, grace periods, session thresholds, performance settings, and the evtspike enable switch are edited from the dashboard. Agents pull the authoritative config on their normal fetch cadence.
Fires the instant drain mode changes. No polling — the OS notifies the service directly.
~0msSecurity Event 4657 tells you who made the change. Attribution you can't get from registry monitoring alone.
Who did itCPU, memory, input delay, disk queue, TCP retransmits, and optional RemoteFX metrics. Configurable sustain windows filter transient spikes.
CPU + Mem + DelayWebhook, ntfy, and email with per-target triggers and repeat intervals. DPAPI-encrypted secrets at rest.
3 channels# Check drain mode status (instant via service pipe) PS> drainctl check 2026-04-02T20:08:56-04:00 [INF] source=service 2026-04-02T20:08:56-04:00 [INF] host=MDS-LDC1-RDS5 2026-04-02T20:08:56-04:00 [INF] drain_mode=ALLOW_ALL_CONNECTIONS value=0 2026-04-02T20:08:56-04:00 [INF] state_since=2026-04-02T18:30:00-04:00 state_duration=1h38m56s 2026-04-02T20:08:56-04:00 [INF] grace_period=1h0m0s 2026-04-02T20:08:56-04:00 [OK ] status=Healthy connections_allowed=true exit=0 # When drain mode is active beyond grace period: 2026-04-02T22:15:00-04:00 [ERR] status=Alert connections_allowed=false exit=1 # Exit code 1 triggers your RMM monitoring threshold
# Rich status object PS> Get-RDSHDrainMode Timestamp : 4/2/2026 8:08:56 PM Host : MDS-LDC1-RDS5 DrainMode : ALLOW_ALL_CONNECTIONS StateSince : 4/2/2026 6:30:00 PM StateDurationSeconds : 5936 Status : Healthy ConnectionsAllowed : True Message : All connections allowed. ExitCode : 0 # Boolean check for scripts and alerts PS> if (Test-RDSHDrainMode) { "OK" } else { "ALERT" } OK # One-liner for monitoring scripts PS> (Get-RDSHDrainMode).Status Healthy
# Machine-readable output for automation PS> drainctl check --format json { "version": "26.119.10", "host": "MDS-LDC1-RDS5", "drain_mode": "ALLOW_ALL_CONNECTIONS", "drain_mode_value": 0, "state_since": "2026-04-02T18:30:00-04:00", "state_duration_seconds": 5936.42, "grace_period_seconds": 3600, "status": "Healthy", "connections_allowed": true, "sessions": { "active_sessions": 12, "disconnected_sessions": 3, "total_sessions": 15, "max_sessions": 25, "utilization_pct": 60 }, "message": "All connections allowed.", "exit_code": 0 }
# View recent state transitions with attribution PS> Get-RDSHDrainHistory -ChangesOnly -Limit 5 Timestamp DrainMode Changed ChangedBy Exit --------- --------- ------- --------- ---- 4/2/2026 10:14:04 PM ALLOW_RECONNECTIONS_PREVENT_NEW.. YES MDS\lissadmin 0 4/2/2026 10:13:32 PM ALLOW_ALL_CONNECTIONS YES MDS\lissadmin 0 4/2/2026 10:10:00 PM ALLOW_RECONNECTIONS_PREVENT_NEW.. YES MDS\lissadmin 0 4/2/2026 8:30:00 PM ALLOW_ALL_CONNECTIONS YES MDS\svcaccount 0 4/2/2026 6:15:00 PM ALLOW_RECONNECTIONS_PREVENT_NEW.. YES MDS\jdoe 0 # Filter in pipeline PS> Get-RDSHDrainHistory | Where-Object Changed | Select Timestamp, ChangedBy
Setup wizard with license acceptance, install mode selection, and configuration options. The recommended way to install interactively.
Same MSI for RMM, SCCM, Intune, or GPO deployment. No UI — configure everything via properties.
msiexec /i LISSTech.DrainCtl.msi /qn
Just the cmdlets — no service, no CLI. Good for quick checks and scripts. Public
builds are currently prerelease; use -AllowPrerelease when needed.
Install-Module LISSTech.DrainCtl -AllowPrerelease
“We monitor 14 session hosts across 3 client sites. Before DrainCtl, we'd find out someone drained a server when users started calling. Now we know before they do.”
— MDS Production Environment, LISS Technologies
LISS Technologies is a NYC-based managed services provider — in business since 1984. We manage Windows infrastructure, RDSH farms, and enterprise environments for our clients.
DrainCtl exists because we needed it. No tool on the market gave us instant drain detection with proper attribution, a farm-wide dashboard, and alerts that understood RDSH semantics — so we built one. It's been running in production at client sites since before this page existed.
We open-source the tools we'd want to use ourselves. If your team manages session hosts, you're the kind of shop we work with.
NYC-based MSP since 1984. Four decades of enterprise Windows infrastructure management.
Every tool we release is running in production at a client site before it ships publicly. DrainCtl monitors live RDSH farms daily.
Apache 2.0. Fork it, deploy it, modify it. We release tools we'd want to exist — not lead-generation demos.