How to Check Active RDP Sessions and User Connections on Windows Server 2012


3 views

To view currently active Remote Desktop Protocol (RDP) sessions on Windows Server 2012, you have several built-in tools at your disposal:

# PowerShell command to list all sessions
query session

Output example:

SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE
console                                     0  Conn    wdcon
rdp-tcp#1         Domain\AdminUser         1  Active  rdpwd
rdp-tcp#2         Domain\DevUser           2  Active  rdpwd
rdp-tcp                                 65536  Listen  rdpwd

For more detailed information including client IP addresses and session durations:

# PowerShell alternative with more details
Get-WmiObject -Class Win32_TSSession -ComputerName $env:COMPUTERNAME | 
Where-Object {$_.SessionId -ne 0} | 
Select-Object SessionId, UserName, ClientName, ConnectTime

The netstat command can help identify active connections:

netstat -ano | findstr 3389

To correlate PID with usernames:

tasklist /FI "PID eq 1234"

For enterprise environments, consider:

  • Remote Desktop Services Manager (built-in)
  • Terminal Services Manager (tsadmin.msc)
  • SolarWinds RDP Monitor

Here's a PowerShell script to log RDP connections:

# Create RDP session log
$LogPath = "C:\Temp\RDPSessions.log"
$Sessions = query session

Add-Content -Path $LogPath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Add-Content -Path $LogPath -Value $Sessions
Add-Content -Path $LogPath -Value "------------------------------------"

Always:

  • Restrict RDP access via GPO
  • Enable Network Level Authentication
  • Monitor event logs (Event ID 21, 22, 23, 24, 25 in Microsoft-Windows-TerminalServices-LocalSessionManager)

When administering a Windows Server 2012 system, monitoring active Remote Desktop Protocol (RDP) connections is crucial for both security and resource management. The built-in Windows tools provide several methods to retrieve this information programmatically.

The query session and qwinsta commands display current sessions:

query session
# or alternatively:
qwinsta

Sample output:

SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE
services                                    0  Disc
console                                     1  Conn
rdp-tcp#14        Administrator             2  Active
rdp-tcp                                 65536  Listen

For more detailed information including IP addresses and connection times:

Get-RDUserSession -ConnectionBroker $env:COMPUTERNAME | 
    Select-Object HostServer, UserName, SessionId, ConnectionState, CreateTime

Or using WMI for older systems:

Get-WmiObject -Class Win32_LogonSession | Where-Object {
    $_.LogonType -eq 10
} | ForEach-Object {
    $session = $_
    Get-WmiObject -Class Win32_LoggedOnUser | Where-Object {
        $_.Dependent.LogonId -eq $session.LogonId
    } | Select-Object @{
        Name="UserName";Expression={$_.Antecedent.Name}
    }, @{
        Name="LogonTime";Expression={$session.StartTime}
    }
}

To get the actual client IP addresses of connected RDP sessions:

netstat -ano | findstr "3389"

Combine with tasklist to identify users:

$connections = netstat -ano | findstr "3389"
foreach ($conn in $connections) {
    $pid = ($conn -split '\s+')[-1]
    $process = tasklist /fi "PID eq $pid" /fo csv | ConvertFrom-Csv
    [PSCustomObject]@{
        Protocol = ($conn -split '\s+')[0]
        LocalAddress = ($conn -split '\s+')[1]
        RemoteAddress = ($conn -split '\s+')[2]
        State = ($conn -split '\s+')[3]
        PID = $pid
        ProcessName = $process.ImageName
        SessionName = $process.SessionName
    }
}

Windows logs RDP connections in the Security event log (Event ID 4624). To query recent connections:

Get-WinEvent -LogName Security -FilterXPath "*[System[EventID=4624]]" -MaxEvents 20 | 
Where-Object { $_.Properties[8].Value -eq 10 } | 
Select-Object TimeCreated, @{Name='User';Expression={$_.Properties[5].Value}}, 
@{Name='SourceIP';Expression={$_.Properties[18].Value}}

For regular monitoring, create a scheduled task that runs this PowerShell script:

$sessions = qwinsta | Where-Object { $_ -match 'rdp' }
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$output = "C:\Temp\RDPSessions_$(Get-Date -Format 'yyyyMMdd').csv"

$sessions | ForEach-Object {
    $sessionInfo = $_ -split '\s+',6 | Where-Object { $_ }
    [PSCustomObject]@{
        Timestamp = $timestamp
        SessionName = $sessionInfo[0]
        Username = $sessionInfo[1]
        ID = $sessionInfo[2]
        State = $sessionInfo[3]
        Type = $sessionInfo[4]
        Device = $sessionInfo[5]
    }
} | Export-Csv -Path $output -Append -NoTypeInformation