2

I detect whether someone is currently connected over RDP using PowerShell:

Get-WinEvent Microsoft-Windows-TerminalServices-LocalSessionManager/Operational | Where-Object {$_.Id -eq 24 -or $_.Id -eq 25} | Select-Object -First 1 -Property *

From that, I can get the IP. Another way to get the same info would be:

netstat -n | findstr ":3389" | findstr "ESTABLISHED"

However, on my network, most users logging in over RDP will be connecting through OpenVPN, so the IP for their sessions is always that of the OpenVPN server.

Now, obviously the RDP host is able to communicate with the original RDP client. How can I find out anything about the identity of that RDP client? (IP, hostname, netbios name, anything that would help me identify the machine or the user)

I can't use the account that's being used to log in to the remote desktop either, because in the particular case I'm interested in, people are share the same logged in session, so it's always the same user on the RDP host.

2
  • 1
    Is AllowRemoteRPCset to 1 on the clients? If yes, try Import-Module PSTerminalServices and get your list using Get-TSSession -ComputerName <RDSH> – bjoster Jun 7 at 20:27
  • 1
    That's actually a very clean solution as well, although there is a typo in your comment @bjoster, it's Import-Module -Name PSTerminalServices, thanks though. – Grismar Jun 8 at 23:14
1

I would search for the client computer name. The %CLIENTNAME% environment variable keeps this value.

On the host in the user session, it will be available from the command line or in a script:

echo %CLIENTNAME%

However, note that on a system that has several users sharing the same session, using a shared user account, this value can go stale.

A more reliable way to get the currently logged in session on the host is by getting the value from the registry. Depending on the version of Windows used, it will sit in one of these locations:

Example 1 (NT 5.2):

[HKEY_USERS\S-1-5-21-***\Volatile Environment]
"CLIENTNAME"="DESKTOP-223XGQ"

Example 2 (NT 6.3):

[HKEY_USERS\S-1-5-21-***\Volatile Environment\3]
"CLIENTNAME"="DESKTOP-223XGQ"

Example 3 (NT 6.1) batch-script runned from user environment:

for /f "tokens=3*" %%i in ('reg query "hkcu\Volatile Environment" /s /v CLIENTNAME^|find/i"CLIENTNAME"') do @echo %%i

Where the *** in S-1-5-21-*** is the user SID.

Note that there will also be a similar HKEY_USERS\S-1-5-21-***_Classes which won't hold the CLIENTNAME subkey.

The approach that will reliable get you a client name is to check HKEY_USERS\S-1-5-21-***\Volatile Environment for a CLIENTNAME subkey and if it's not there, to enumerate the keys in Volatile Environment and check any of them that have a an all integer value name (1, 2, etc.) for a CLIENTNAME subkey.

A Python function that does this:

def get_client_name():
    with ConnectRegistry(None, HKEY_USERS) as root:
        try:
            n = 0
            while True:
                user_key = EnumKey(root, n)
                if user_key.startswith('S-1-5-21-') and not user_key.endswith('_Classes'):
                    with OpenKey(root, f"{user_key}\Volatile Environment", 0, KEY_READ) as ve_key:
                        try:
                            return QueryValueEx(ve_key, 'CLIENTNAME')[0]
                        except FileNotFoundError:
                            pass
                        try:
                            m = 0
                            while True:
                                client = EnumKey(ve_key, m)
                                try:
                                    with OpenKey(ve_key, f'{client}', 0, KEY_READ) as client_key:
                                        return QueryValueEx(client_key, 'CLIENTNAME')[0]
                                except (OSError, FileNotFoundError):
                                    pass
                                m += 1
                        except OSError:
                            pass
                n += 1
        except OSError:
            return None

And all theese ways are applicable to Windows Terminal Server and Citrix Servers (checked on Receiver 4.12).

Another approach is to install a PowerShell cmdlet and capture the information with that:

Install-Module -Name PSTerminalServices
Get-TSSession

Or, specifically

Get-TSSession | ft ClientName
3
  • As far as I know, %CLIENTNAME% is specific to Citrix? I was asking about RDP (i.e. Windows Remote Desktop) However, your Volatile Environment suggestion does help somewhat, as the connecting hostname is available under /1/CLIENTNAME in that hive. Can you amend your answer to reflect both solutions for RDP and Citrix, so I can accept? – Grismar Jun 2 at 22:42
  • I don't know khow to get Citrix client-name. My answer responds to Windows Terminal Service (by RDP). From Windows version registry variable position may vary. It can be Volatile Environment or it's subkey. But you can get value from environment variable by any script running in user environement: PS, VBscript, batch-file, etc. I reccoment to search for clientname by my advise. Then write here on troubles. – Daemon-5 Jun 3 at 2:55
  • I've proposed a change to the answer that should fix all. – Grismar Jun 4 at 0:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.