Es gibt Umstände, da möchte man Wissen von welchem System aus eine RDP-Verbindung hergestellt wurde, wie deren Status ist und mehr.
Die einfachste Möglichkeit ist via “Task-Manager – Benutzer” und die entsprechenden Spalten anzeigen lassen. Bordmittel an Befehlen wären zum Beispiel
- query user
- query session
- qwinsta
Allen gemein ist, das sie im Gegensatz zum Task-Manager nicht den Clientname anzeigen. Möchte man das Ganze via Skript lösen geht das so:
Add-Type -MemberDefinition @'
[DllImport("wtsapi32.dll", CharSet = CharSet.Unicode)]
public static extern bool WTSQuerySessionInformation(
IntPtr hServer,
int sessionId,
int infoClass,
out IntPtr ppBuffer,
out int pBytesReturned);
[DllImport("wtsapi32.dll")]
public static extern void WTSFreeMemory(IntPtr pMemory);
'@ -Name 'WtsApi' -Namespace 'Win32'
$WTS_CURRENT_SERVER = [IntPtr]::Zero
$WTSUserName = 5
$WTSClientName = 10
$WTSSessionName = 6
$WTSConnectState = 8
function Get-WTSInfo($sessionId, $infoClass) {
$buffer = [IntPtr]::Zero
$bytes = 0
if ([Win32.WtsApi]::WTSQuerySessionInformation(
$WTS_CURRENT_SERVER, $sessionId, $infoClass,
[ref]$buffer, [ref]$bytes)) {
$value = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($buffer)
[Win32.WtsApi]::WTSFreeMemory($buffer)
return $value
}
return $null
}
function Get-WTSConnectState($sessionId) {
$buffer = [IntPtr]::Zero
$bytes = 0
if ([Win32.WtsApi]::WTSQuerySessionInformation(
$WTS_CURRENT_SERVER, $sessionId, $WTSConnectState,
[ref]$buffer, [ref]$bytes)) {
$state = [System.Runtime.InteropServices.Marshal]::ReadInt32($buffer)
[Win32.WtsApi]::WTSFreeMemory($buffer)
switch ($state) {
0 { return 'Aktiv' }
1 { return 'Verbunden' }
2 { return 'Verbindung wird hergestellt' }
3 { return 'Inaktiv' }
4 { return 'Getrennt' }
5 { return 'Abgemeldet' }
6 { return 'Zurückgestellt' }
7 { return 'Zurückgesetzt' }
8 { return 'Wird beendet' }
default { return "Unbekannt ($state)" }
}
}
return $null
}
qwinsta 2>$null | Select-Object -Skip 1 | ForEach-Object {
if ($_ -match '\s+(\d+)\s+') {
$id = [int]$matches[1]
$user = Get-WTSInfo $id $WTSUserName
$client = Get-WTSInfo $id $WTSClientName
$session = Get-WTSInfo $id $WTSSessionName
$status = Get-WTSConnectState $id
if ($user) {
[PSCustomObject]@{
SessionID = $id
Sitzung = $session
Benutzer = $user
Clientname = $client
Status = $status
}
}
}
}
Die Ausgabe sieht dann beispielsweise so aus:
SessionID : 1 Sitzung : RDP-Tcp#16 Benutzer : administrator Clientname : PC06 Status : Aktiv SessionID : 2 Sitzung : Benutzer : homeoffice Clientname : Status : Getrennt
Das Ganze funktioniert sowohl unter Windows Server als auch Windows Clients.
Dieses Skript wurde mittels Anthropic Claude erstellt.
Update 21.04.2026
Das Skript hat sich schon mehrfach als nützlich erwiesen. Nachfolgend eine erweiterte Fassung die den Anzeigenamen und die IP-Adresse (des RDP-Clients) mit ausgibt:
Add-Type -MemberDefinition @'
[DllImport("wtsapi32.dll", CharSet = CharSet.Unicode)]
public static extern bool WTSQuerySessionInformation(
IntPtr hServer,
int sessionId,
int infoClass,
out IntPtr ppBuffer,
out int pBytesReturned);
[DllImport("wtsapi32.dll")]
public static extern void WTSFreeMemory(IntPtr pMemory);
'@ -Name 'WtsApi' -Namespace 'Win32'
Add-Type -MemberDefinition @'
[StructLayout(LayoutKind.Sequential)]
public struct WTS_CLIENT_ADDRESS {
public uint AddressFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] Address;
}
'@ -Name 'WtsStructs' -Namespace 'Win32' -WarningAction SilentlyContinue
$WTS_CURRENT_SERVER = [IntPtr]::Zero
$WTSUserName = 5
$WTSDomainName = 7
$WTSClientName = 10
$WTSSessionName = 6
$WTSConnectState = 8
$WTSClientAddress = 14
function Get-WTSInfo($sessionId, $infoClass) {
$buffer = [IntPtr]::Zero
$bytes = 0
if ([Win32.WtsApi]::WTSQuerySessionInformation(
$WTS_CURRENT_SERVER, $sessionId, $infoClass,
[ref]$buffer, [ref]$bytes)) {
$value = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($buffer)
[Win32.WtsApi]::WTSFreeMemory($buffer)
return $value
}
return $null
}
function Get-WTSConnectState($sessionId) {
$buffer = [IntPtr]::Zero
$bytes = 0
if ([Win32.WtsApi]::WTSQuerySessionInformation(
$WTS_CURRENT_SERVER, $sessionId, $WTSConnectState,
[ref]$buffer, [ref]$bytes)) {
$state = [System.Runtime.InteropServices.Marshal]::ReadInt32($buffer)
[Win32.WtsApi]::WTSFreeMemory($buffer)
switch ($state) {
0 { return 'Aktiv' }
1 { return 'Verbunden' }
2 { return 'Verbindung wird hergestellt' }
3 { return 'Inaktiv' }
4 { return 'Getrennt' }
5 { return 'Abgemeldet' }
6 { return 'Zurückgestellt' }
7 { return 'Zurückgesetzt' }
8 { return 'Wird beendet' }
default { return "Unbekannt ($state)" }
}
}
return $null
}
function Get-WTSClientIP($sessionId) {
$buffer = [IntPtr]::Zero
$bytes = 0
if ([Win32.WtsApi]::WTSQuerySessionInformation(
$WTS_CURRENT_SERVER, $sessionId, $WTSClientAddress,
[ref]$buffer, [ref]$bytes)) {
$addr = [System.Runtime.InteropServices.Marshal]::PtrToStructure(
$buffer, [type][Win32.WtsStructs+WTS_CLIENT_ADDRESS])
[Win32.WtsApi]::WTSFreeMemory($buffer)
if ($addr.AddressFamily -eq 2) {
return "$($addr.Address[2]).$($addr.Address[3]).$($addr.Address[4]).$($addr.Address[5])"
}
elseif ($addr.AddressFamily -eq 23) {
$ipv6 = [System.Net.IPAddress]::new($addr.Address[2..17])
return $ipv6.ToString()
}
}
return $null
}
function Get-DisplayName($username, $domain) {
if (-not $username) { return $null }
try {
# Versuch über Active Directory (ADSI)
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.Filter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=$username))"
$searcher.PropertiesToLoad.Add("displayName") | Out-Null
$result = $searcher.FindOne()
if ($result) {
return $result.Properties["displayName"][0]
}
}
catch {}
try {
# Fallback: lokaler Benutzer
$localUser = Get-LocalUser -Name $username -ErrorAction SilentlyContinue
if ($localUser -and $localUser.FullName) {
return $localUser.FullName
}
}
catch {}
return $null
}
qwinsta 2>$null | Select-Object -Skip 1 | ForEach-Object {
if ($_ -match '\s+(\d+)\s+') {
$id = [int]$matches[1]
$user = Get-WTSInfo $id $WTSUserName
$domain = Get-WTSInfo $id $WTSDomainName
$client = Get-WTSInfo $id $WTSClientName
$session = Get-WTSInfo $id $WTSSessionName
$status = Get-WTSConnectState $id
$ip = Get-WTSClientIP $id
$displayName = Get-DisplayName $user $domain
if ($user) {
[PSCustomObject]@{
SessionID = $id
Sitzung = $session
Benutzer = $user
Anzeigename = $displayName
Clientname = $client
ClientIP = $ip
Status = $status
}
}
}
}
Wie hat Dir der Artikel gefallen ?
Du möchtest den Blog unterstützen ?
Neben PayPal.ME gibt es noch weitere Möglichkeiten, lies hier wie du diesen Blog unterstützen kannst.

Verheiratet, Vater von zwei Kindern, eines an der Hand, eines im Herzen. Schon immer Technik-Freund, seit 2001 in der IT tätig und seit über 15 Jahren begeisterter Blogger. Mit meiner Firma IT-Service Weber kümmern wir uns um alle IT-Belange von gewerblichen Kunden und unterstützen zusätzlich sowohl Partner als auch Kollegen.

XING











Schreibe einen Kommentar