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


12 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