Getting Client IP Addresses and its Geolocation from Remote Desktop Gateway Sessions

To get the IP addresses of the remote desktop sessions behind a Remote Desktop Gateway, you need to open RD Gateway Manager, go to Monitoring section and check each of the connected sessions to find their IP addresses. If you want to look further for their geolocations as well, you would search the IP address in one of the geolocation websites to find out.

That is just too many steps involved and there got to be a better way to handle this if I want to monitor all incoming remote sessions on a regular consistent basis. Time to ask PowerShell for help.

You can use Get-WmiObject cmdlet to query the Win32_TSGatewayConnection class for live session data on the Gateway server. Like this:

Get-WmiObject -class "Win32_TSGatewayConnection" -namespace "root\cimv2\TerminalServices" -ComputerName remote_server -Authentication 6

To get the geolocation info, you can call up Invoke-RestMethod cmdlet that deals with HTTP/HTTPs requests related to Representational State Transfer (REST) web services that return richly structured data, such as XML or JSON. It’s a perfect candidate to perform the call and display the result in a nicely formatted way. It runs something like this:

Invoke-RestMethod -Uri "http://ipinfo.io/$ipaddress"

For more information about getting Geolocation info from PowerShell, check out this post.

Putting together, here is the code you can use to get all live sessions’ IP addresses and their geolocation info on the Remote Gateway server.

$ts = Get-WmiObject -class "Win32_TSGatewayConnection" -namespace "root\cimv2\TerminalServices" -ComputerName remote_server -Authentication 6
$ofs = "`r`n`r`n"
$body = "Gateway connections: " + $ofs

foreach ($connection in $ts)
{
    $username = $connection.username
    $ip = $connection.clientaddress
    $geo = Invoke-RestMethod -Uri "http://ipinfo.io/$ip"
    $body = $body + $connection.ConnectedTime + $username + $geo + $ofs
} 
$body

It works great to get data from the live sessions. What about the closed sessions that you missed? You can create a scheduled task that triggers a PowerShell script every time a session goes live. The trigger needs to be based on the event, more specifically, Microsoft-Windows-TerminalServices-Gateway/Operational. See the trigger below:

The script will then collect the IP info of that session and save it to the event log.

$ts = Get-WmiObject -class "Win32_TSGatewayConnection" -namespace "root\cimv2\TerminalServices" -ComputerName Remote_Server -Authentication 6  | Sort-Object ConnectionDuration -Desc
$ofs = "`r`n`r`n"
$body = "Gateway connections: " + $ofs

foreach ($connection in $ts)
{
    $username = $connection.username
    $ip = $connection.clientaddress
    $geo = Invoke-RestMethod -Uri "http://ipinfo.io/$ip"
} 

$body = $body + $connection.ConnectedTime + ": " +$username + $geo + $ofs

$server = "remote_server"
$logname = "application"
#New-EventLog -ComputerName $server -Logname $logname -Source "MyApp"
Write-EventLog -ComputerName $server -Logname $logname -Source "MyApp" -EventID 3001 -Message $body

Note that the script only extracts the last session from the session collection so only the newest info will be saved into the log. Once the data is saved in the event log, I can run another PowerShell script to collect and send them to me via email. And I can schedule that script to run on a daily basis.

5 thoughts on “Getting Client IP Addresses and its Geolocation from Remote Desktop Gateway Sessions

  1. Hi Kent,
    How can you create the mentioned scheduled task that triggers a PowerShell script every time a session goes live? What event id should be monitored for this?
    Thank you and best regards,
    Roland

  2. Hi Kent,
    I am running this both manually and as a task.
    It only seems to capture the last record, rather than looping through each connection, writing to log and then doing the next one.

    Am I missing something ?
    $ts should return several “$connection” users to record

  3. Hi Kent,

    I’ve implemented the task scheduler script and it seems to work, but doesn’t seem to trigger as often as it should. Should it be running on the gateway server? Or on each RDS server?

  4. As far as i can tell. With the task scheduler on the gateway running the script it only triggers whenever I logon directly to the gateway.

Leave a Reply

Your email address will not be published. Required fields are marked *