In enterprise environments, Configuration Manager (SCCM/MECM) servers are often shared by multiple administrators for day-to-day operations. While this centralized access improves efficiency, it can also introduce a common operational issue: inactive/disconnected RDP sessions consuming server resources.
In this post, I’ll walk through a lightweight and effective solution I implemented at a customer site to automatically identify and log off disconnected sessions, helping to reclaim CPU and memory resources.
At the customer environment, multiple administrators were logging into the SCCM server to perform their tasks. However, once done:
- Many users closed their RDP sessions without logging off
- Sessions transitioned into a Disconnected (Disc) state
- Applications continued running in those sessions
- Over time, this caused high CPU and memory usage
The server monitoring team reported frequent performance alerts, and manual cleanup wasn’t sustainable.
To address this, I developed a PowerShell script that:
- Retrieves all active sessions using
quser - Identifies sessions in a Disconnected (Disc) state
- Logs off those sessions automatically
- Records all actions in a log file for auditing
The script can be scheduled to run at regular intervals (e.g., every 2–4 hours) using Task Scheduler.
PowerShell script:
<#
.SYNOPSIS
Logs off all disconnected Remote Desktop (RDP) user sessions on a Windows server.
.DESCRIPTION
This script enumerates all user sessions using the built-in quser.exe utility and identifies
sessions that are in a "Disconnected" (Disc) state. Any disconnected sessions are automatically
logged off using logoff.exe to release system resources and ensure idle sessions do not remain
active indefinitely.
The script also creates a transcript log for auditing and troubleshooting purposes.
Administrators can optionally exclude specific service or administrative accounts from being
logged off by modifying the conditional statement within the script.
.EXAMPLE
.\ForceLogoffDisconnectedSessions.ps1
Scans the local server for disconnected sessions and logs them off.
.EXAMPLE
Create a Scheduled Task to run every hour:
powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\ForceLogoffDisconnectedSessions.ps1"
#>
Start-Transcript -Path 'C:\Temp\forcelogoffdisconnectedsessions.log'
# Get all sessions
$sessionOutput = quser.exe
foreach ($line in $sessionOutput) {
$textLine = $line.Trim()
# Skip header and empty lines
if ($textLine -match 'USERNAME\s+SESSIONNAME' -or $textLine -eq '') { continue }
# Extract session details using regex
if ($textLine -match '^(?<Username>\S+)\s+(?<SessionName>\S+)?\s+(?<ID>\d+)\s+(?<State>\S+)\s+(?<IdleTime>\S+)?\s+(?<LogonTime>.+)?$') {
$username = $matches['Username']
$sessionId = $matches['ID']
$sessionState = $matches['State']
if ($sessionState -eq 'Disc') {
# Example: Exclude a service account
# if ($sessionState -eq "Disc" -and $username -ne "svc_account")
Write-Host "Logging off disconnected session for user '$username' (Session ID: $sessionId)..."
# Force logoff
logoff.exe $sessionId /v
}
}
}
Stop-Transcript
Scheduling the Script:
To automate the cleanup:
- Open Task Scheduler
- Create a new task
- Configure:
- Trigger: Every 4–6 hours
- Action:
powershell.exe -ExecutionPolicy Bypass -Command "& ""C:\Temp\ForceLogoffDisconnectedSessions.ps1"""
- Trigger: Every 4–6 hours
- Run with highest privileges
- Use a service account with appropriate rights
Disconnected RDP sessions are a silent contributor to performance issues in shared infrastructure environments like SCCM servers. With a simple PowerShell script and scheduled task, you can proactively manage sessions and maintain optimal server performance.
If you're facing similar issues, this approach provides a quick win with minimal overhead.