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


1 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