How to Force Disconnect Remote Desktop Sessions to Resolve “Maximum Connections Exceeded” Error


3 views

When attempting to connect to a Windows Server via Remote Desktop Protocol (RDP), you might encounter the frustrating error:

The terminal server has exceeded the maximum number of allowed connections.

This typically occurs when the server's RDP connection limit (usually 2 for standard Windows Server installations) has been reached by other active sessions.

Here's the most efficient way to resolve this through PowerShell (run as Administrator):

# List all active sessions
query session /server:SERVERNAME

# Disconnect a specific session
reset session SESSION_ID /server:SERVERNAME

Method 1: Using Command Prompt

# First, identify active sessions
query user /server:SERVERNAME

# Sample output:
USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
john.doe              console             1  Active      none   10/15/2023 8:30 AM
jane.smith           rdp-tcp#12           2  Active      none   10/15/2023 9:15 AM

# To disconnect a session (ID 2 in this case):
logoff 2 /server:SERVERNAME

Method 2: PowerShell Approach

$server = "YOUR_SERVER_NAME"
$sessions = qwinsta /server:$server | Where-Object { $_ -match 'Active' }

# Display sessions
$sessions | ForEach-Object {
    $sessionInfo = $_ -split '\s+'
    Write-Host "ID: $($sessionInfo[2]) User: $($sessionInfo[1])"
}

# Disconnect specific session
Invoke-Command -ComputerName $server -ScriptBlock {
    param($sessionId)
    logoff $sessionId
} -ArgumentList 2

Method 3: Using Remote Desktop Services Manager

  1. Open "Remote Desktop Services Manager" (tsadmin.exe)
  2. Connect to the target server
  3. Right-click on the session you want to disconnect
  4. Select "Disconnect" or "Reset"

For frequent use, create this PowerShell script (Save as ForceRDPDisconnect.ps1):

param(
    [string]$ServerName,
    [int]$MaxIdleMinutes = 60
)

$sessions = qwinsta /server:$ServerName | Where-Object { $_ -match 'Disc' -or $_ -match 'Active' }

foreach ($session in $sessions) {
    $sessionInfo = $session -split '\s+'
    $sessionId = $sessionInfo[2]
    $state = $sessionInfo[3]
    $idleTime = $sessionInfo[4]
    
    if ($state -eq 'Disc' -or ($state -eq 'Active' -and $idleTime -gt $MaxIdleMinutes)) {
        logoff $sessionId /server:$ServerName
        Write-Host "Disconnected session $sessionId (State: $state, Idle: $idleTime)"
    }
}

Consider these registry tweaks (backup first!):

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]
"fDenyTSConnections"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]
"MaxInstanceCount"=dword:0000000a

This enables RDP and increases maximum connections to 10 (adjust as needed).


The Windows Server Remote Desktop Services enforces a default limit of 2 simultaneous connections for administrative purposes (or more depending on licensing). When you encounter the error:

The terminal server has exceeded the maximum number of allowed connections.

It typically means all available RDP slots are occupied by other users. As an admin, you need tools to remotely manage these sessions.

The most efficient way is through Windows' built-in command line utilities:

query session /server:SERVERNAME

This lists all active sessions with their IDs. To terminate a session:

rwinsta /server:SERVERNAME SESSIONID

Example workflow:

C:\>query session /server:APPSERVER01
SESSIONNAME       USERNAME           ID  STATE   TYPE        DEVICE
console           jsmith              0  Active
rdp-tcp#1         bjohnson            1  Active
rdp-tcp#2         mwilson             2  Active

C:\>rwinsta /server:APPSERVER01 2

For advanced management, PowerShell provides better control:

# Get all remote sessions
$sessions = qwinsta /server:SERVERNAME | Where-Object { $_ -notmatch '^ SESSIONNAME' } | 
            ForEach-Object { $_.Trim() -replace '\s+',',' | ConvertFrom-Csv -Header @('SessionName','Username','ID','State','Type','Device') }

# Force logoff specific user
Invoke-Command -ComputerName SERVERNAME -ScriptBlock {
    param($sessionId)
    logoff $sessionId
} -ArgumentList $sessionIdToTerminate

You can wrap this in a function for reuse:

function Reset-RDPSession {
    param(
        [string]$Server,
        [string]$Username
    )
    $session = qwinsta /server:$Server | 
               Where-Object { $_ -match $Username } |
               ForEach-Object { ($_ -split '\s+')[2] }
    
    if($session) {
        rwinsta /server:$Server $session
        Write-Host "Terminated session $session for $Username"
    }
}

For GUI lovers:

  1. Open Remote Desktop Services Manager (run 'tsadmin.msc')
  2. Right-click your server in the left pane and select Connect
  3. Navigate to the Users tab
  4. Right-click any user and select Log Off or Disconnect

To prevent this issue:

  • Configure Group Policy: Computer Configuration -> Administrative Templates -> Windows Components -> Remote Desktop Services -> Connections -> Limit Number of Connections
  • Implement proper session timeout policies
  • Consider using RDPCAL licensing for more concurrent connections

Here's a complete PowerShell solution that checks and frees slots:

function Reset-RDPConnectionSlot {
    param(
        [Parameter(Mandatory=$true)]
        [string]$ComputerName,
        
        [int]$MinimumFreeSlots = 1
    )
    
    try {
        $sessions = qwinsta /server:$ComputerName 2>&1
        
        if($sessions -is [System.Management.Automation.ErrorRecord]) {
            throw $sessions.Exception
        }
        
        $activeSessions = ($sessions | Where-Object { $_ -match '^\s*rdp' }).Count
        
        if($activeSessions -ge (2 - $MinimumFreeSlots)) {
            $oldestSession = $sessions | 
                            Where-Object { $_ -match '^\s*rdp' } |
                            Select-Object -First 1 |
                            ForEach-Object { ($_ -split '\s+')[2] }
            
            if($oldestSession) {
                rwinsta /server:$ComputerName $oldestSession
                return "Freed session ID $oldestSession"
            }
        }
        
        return "No action needed"
    }
    catch {
        Write-Error "Error managing RDP sessions: $_"
    }
}