How to Retrieve Remote Desktop Client IP Address and Execute Scripts on RDP Connection Using PowerShell


11 views

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:

  1. Computer Configuration → Policies → Windows Settings → Scripts (Startup/Shutdown)
  2. 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