How To Obtain IP Addresses Of Remote Desktop Clients With PowerShell
Posted on December 10, 2019
- and tagged as
- powershell,
- rds
If you’ve ever managed a terminal server or RDS chances are there has been a need to identify the IP address of connected clients.
Task manager gives us the client hostname but sometimes DNS can have stale entries or the client can be on the remote side of a VPN. We can use tools like netstat, but this only gives us connected IPs, not the associated usernames. The old Remote Desktop Services Manager showed the client IP along with the username, but it is no longer present Server 2012 and newer.
A simple way I’ve been using is to parse the Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational
event log. This log, under EventId 1149
shows each successful RDS authentication event, and contains the username, IP address, and timestamp.
The snippet below is essentially a shortcut to manually checking the RemoteConnectionManager
logs. It pulls current users from quser
so we only display data for existing sessions, then parses the event log (limiting the query to the last 31 days as we don’t need to pull everything), correlates the two, finally displaying the connected users, the IP they’re connecting from, and a timestamp of when they authenticated.
$CurrentUsers = quser
$CurrentUsers = $CurrentUsers[1..$CurrentUsers.Length] | % {$_.trim().Split(" ")[0].Replace(">", "")}
$Events = Get-WinEvent -FilterHashtable @{
Logname = 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational'
ID = 1149
StartTime = (Get-Date).AddDays(-31)
}
$EventObjects = @()
$Events | % {
$EventXML = [xml]$_.ToXml()
$obj = New-Object -TypeName PSObject -Property @{
Username = $EventXML.Event.UserData.EventXML.Param1
IP = $EventXML.Event.UserData.EventXML.Param3
Timestamp = [datetime]$EventXML.Event.System.TimeCreated.SystemTime
}
$EventObjects += $obj
}
$CurrentSessions = $CurrentUsers | ForEach-Object {
$EventObjects | Sort-Object -Property Timestamp -Descending | Where-Object Username -eq $_ | Select-Object -First 1
}
$CurrentSessions | Select-Object Username, IP, Timestamp
Which results in the following sample output.
Username IP Timestamp
-------- -- ---------
user1 10.83.x.x 10/12/2019 4:25:59 PM
user2 10.83.x.x 10/12/2019 6:48:06 PM
One caveat with this method is that that if a user connected through an RD Gateway (keep in mind local connections bypass the RD Gateway by default), the event log entry will show the gateway IP address instead of the client. Gateway entries are logged in Microsoft-Windows-TerminalServices-Gateway/Operational
, EventId 302
, however, this has not been incorporated into the script at this stage.