When managing Windows Servers, you'll often need to identify connected RDP clients. Here's the most reliable PowerShell method for Windows Server 2008 R2:
# PowerShell command to find RDP client IPs
Get-NetTCPConnection -State Established -LocalPort 3389 |
Select-Object RemoteAddress, RemotePort |
Where-Object { $_.RemoteAddress -ne '127.0.0.1' } |
Format-Table -AutoSize
For older systems without Get-NetTCPConnection:
netstat -ano | findstr ":3389.*ESTABLISHED"
To trigger actions when users connect via RDP, we can use Windows Event Log monitoring:
# Create a scheduled task triggered by Event ID 21 (Logon)
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\scripts\rdp_connect.ps1"
$trigger = New-ScheduledTaskTrigger -AtLogOn
$principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM"
Register-ScheduledTask -TaskName "RDP Connect Handler" -Action $action -Trigger $trigger -Principal $principal
Here's a comprehensive script that logs RDP connections with client IPs:
# rdp_monitor.ps1
$logFile = "C:\logs\rdp_connections.csv"
# Check if log exists, create headers if not
if (-not (Test-Path $logFile)) {
"Timestamp,ClientIP,Username" | Out-File $logFile -Encoding UTF8
}
# Get connection info
$connections = Get-NetTCPConnection -State Established -LocalPort 3389 |
Where-Object { $_.RemoteAddress -ne '127.0.0.1' }
foreach ($conn in $connections) {
$session = qwinsta | Where-Object { $_ -match "Active" }
$username = ($session -split "\s+")[1]
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp,$($conn.RemoteAddress),$username" | Out-File $logFile -Append -Encoding UTF8
}
For enterprise environments, consider these Group Policy configurations:
- Computer Configuration → Policies → Windows Settings → Scripts (Startup/Shutdown)
- User Configuration → Policies → Windows Settings → Scripts (Logon/Logoff)
When implementing RDP connection tracking:
- Store logs securely with proper access controls
- Validate all script inputs to prevent injection
- Consider performance impact for high-traffic servers
- Comply with privacy regulations regarding connection logging
# Example secure logging implementation
$securePath = "C:\ProgramData\RDPTracking\"
if (-not (Test-Path $securePath)) {
New-Item -ItemType Directory -Path $securePath -Force
icacls $securePath /grant "SYSTEM:(OI)(CI)F" /grant "Administrators:(OI)(CI)F"
}
When managing Windows Server 2008 R2, you can extract the client IP address through several methods. Here's the most reliable PowerShell approach:
# PowerShell command to get RDP client IP
Get-NetTCPConnection -State Established | Where-Object { $_.LocalPort -eq 3389 } |
Select-Object RemoteAddress, RemotePort
For older systems without Get-NetTCPConnection, use netstat:
netstat -ano | findstr ":3389" | findstr "ESTABLISHED"
Windows Event Log provides the most robust method for triggering actions on RDP connections. First, identify the relevant event:
# Check Terminal Services events
Get-WinEvent -LogName 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational' |
Where-Object { $_.Id -eq 21 -or $_.Id -eq 25 }
Create a scheduled task that triggers on Event ID 21 (session connect):
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\scripts\rdp_hook.ps1"
$trigger = New-ScheduledTaskTrigger -AtLogOn
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopOnIdleEnd
Register-ScheduledTask -TaskName "RDP Connection Hook" -Action $action -Trigger $trigger -Settings $settings
Here's a complete example script that logs connections to a file:
# rdp_hook.ps1
$clientIP = (Get-NetTCPConnection -State Established -LocalPort 3389).RemoteAddress
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"[$timestamp] RDP connection from $clientIP" | Out-File "C:\logs\rdp_connections.log" -Append
# Optional: Execute additional commands
Start-Process "C:\scripts\welcome.bat"
For more complex scenarios, consider using the Win32_SessionProcess class:
$query = "SELECT * FROM Win32_SessionProcess WHERE LogonType = 10"
Register-WmiEvent -Query $query -Action {
param($event, $args)
# Your custom logic here
Write-Host "RDP session detected!"
}
Remember to:
- Run scripts with appropriate permissions
- Validate all input before processing
- Secure sensitive connection data
- Test thoroughly in staging environments