Markus fragte heute in der Microsoft Windows Vista Netzwerk Newsgroup (microsoft.public.de.windows.vista.netzwerk) danach, wie man denn verhindern könne, dass ein Benutzer einen bereits angemeldeten Benutzer via RDP die Sitzung “klaut”.
Zu Beginn sei gesagt, dass mir zumindest nicht bekannt ist, wie man 100%-ig sicher die Übernahme verhindern kann. Aber, und hier setzt meine Lösung an, man kann dem Benutzer, der eine neue Verbindung aufbauen möchte eine Meldung präsentieren, dass bereits ein anderer Benutzer angemeldet ist.
Ich habe vor einer Weile genau diesen Fall gehabt. Ein PC bzw. eine virtuelle Maschine mit Windows XP Professional wird abwechselnd von verschiedenen Benutzern via Remote Desktop verwendet, da dort eine Warenwirtschaftslösung installiert ist. Da sich die Benutzer dann immer gegenseitig raus gekickt haben, habe ich ein paar Skripte entwickelt die ich nachfolgend kurz vorstelle.
Wie funktioniert nun das Ganze? Relativ einfach. Auf einem gemeinsam genutzten Netzlaufwerk liegen die Skripte und auf den Desktops ist eine Verknüpfung zu einem dieser Skripte hinterlegt. Wenn ein Benutzer nun die Verbindung aufbauen möchte, so startet er ein Skript über die Verknüpfung. Dieses Skript prüft, ob eine Status-Datei vorhanden ist. Falls keine Status-Datei vorhanden ist, dann wird einfach eine Verbindung aufgebaut. Falls eine Status-Datei gefunden wird, bedeutet das, dass ein Benutzer via RDP oder Lokal angemeldet ist, dann wird eine Meldung angezeigt, dass bereits eine Verbindung besteht. Es wird angezeigt, von welchem Computer aus die Verbindung besteht, seit wann die Verbindung besteht und ob man sich dennoch verbinden möchte.
Der Quellcode (AutoIt) und die Exe-Dateien gibt es hier zum Download.
Hinweis: Wie bereits erwähnt, habe ich das Ganze vor ein paar Jahren geschrieben. Ich weiß nicht, ob es unter Windows Vista, Windows 7, 32-/64-Bit läuft! Ferner müssen bestimmte Berechtigungen für das Netzlaufwerk und die Registry (Lesen in HKCU, sollte Standard sein) vorhanden sein.
Voraussetzungen
1x Windows XP Professional mit aktivierten Remotedesktop (“RDP-Server”)
1x Netzlaufwerk für den gemeinsamen Zugriff der RDP-Clients (Skript- und Status-Ablage)
Windows XP Clients mit verbundenem Netzlaufwerk (Berechtigungen [Lesen/Schreiben] beachten)
1x RDP-Datei mit den Voreinstellungen für die Remote Desktop-Verbindung
Installation
Auf dem Netzlaufwerk den Inhalt des Ordners bin aus dem Zip-Archiv ablegen. In diesen Ordner ebenfalls die RDP-Datei ablegen. Auf den Arbeitsplätzen eine Verknüpfung zur RDStateCheck.exe hinterlegen.
Tipp: Die Verknüpfung umbenennen in den Computernamen, zu dem man sich verbindet.
Die Datei RDConsole.exe in den Autostart des “RDP-Servers” verknüpfen. Die Datei RDStateReset.cmd via Gruppenrichtlinie als Abmelde-Skript auf dem “RDP-Server” einrichten.
Konfiguration
Den Namen der RDP-Datei in die RDState.ini eintragen.
Das Skript RDStateReset.cmd anpassen (Laufwerksbuchstabe des Netzlaufwerks).
Update 09.02.2023
Der Beitrag ist schon recht alt und die Lösung ist noch viel älter. Unter Windows 10 und neuer ist zudem der Registry-Eintrag für den SESSIONNAME mittlerweile sozusagen einen Stock tiefer in einem Schlüssel der der Session-ID entspricht gerutscht:
HKEY_CURRENT_USER\Volatile Environment\1
D.h. die “RDConsole.exe” funktioniert nicht mehr. An dieser Stelle vielen Dank an Heiko für den Hinweis und die Infos (siehe Kommentare). Als mögliche schnelle Alternative hier ein “RDConsole.exe”-Ersatz in Batch-Form (*.bat, *.cmd):
@echo off rem Konsolen-Sitzung abfragen query session | find /i "console" > session.txt rem Die Session-ID der Konsole ermitteln set /p ID=< session.txt rem Variable kuerzen (Anfangen bei 41, 5 Zeichen lang) set ID=%ID:~41,5% rem Leerzeichen entfernen set ID=%ID: =% rem Sessionname aus der Registry auslesen reg query "HKCU\Volatile Environment\%ID%" /v SESSIONNAME | find /i "console" > NUL 2>&1 if %errorlevel% equ 0 ( echo Verbunden seit %time% am %date% > RDState.txt echo von Computer: %SESSIONNAME% >> RDState.txt ) del /q session.txt > NUL 2>&1
Die Formatierung von Datum und Uhrzeit sind hier noch nicht wie bei der AutoIt-Lösung. Das ließe sich allerdings auch noch umsetzen.
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 10 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.
Hallo Andy,
ein super Ansatz für genau mein Problem. Brauche jedoch noch etwas Hilfe….
Umfeld:
Mehrere Nutzer melden sich mit gleichem Userprofil auf W10 Workstation an. Ist nun einer bereits per remote verbunden, kann momentan jeder weitere diesen rauskicken.
Ich habe die Schitte bisher so umgesetzt und einen Teilerfolg (RDState.txt wird auf Netzlaufwerk erstellt).
Momentan klemmt es bei
“Die Datei RDStateReset.cmd via Gruppenrichtlinie als Abmelde-Skript auf dem “RDP-Server” einrichten.”
Wie setzte ich das auf der W10 Workstation und in welcher Gruppenrichtlinie um?
Danke Heiko
Hallo Heiko,
puh, das ist ein recht alter Beitrag von 2009 und die Lösung als solches ist sogar noch älter (Schätzungsweise round about 2007).
Ich weiß nicht ob das alles heute noch so funktioniert. Überhaupt nicht mit einbezogen ist das Thema, wenn einer die RDP-Sitzung einfach trennt.
Das Ganze lässt sich allerdings sicher aktualisieren, falls benötigt.
Jedenfalls die GPO die du suchst ist:
Benutzereinstellungen – Windows-Einstellungen – Skripts (Anmelden/Abmelden) – Abmelden
Hallo Andy,
Danke für das schnelle Feedback. Habe das so angepasst……
Wenn sich der aktuell mit der Workstation verbundene User korrekt abmeldet, und nicht einfach
nur das Remotefenster mit (x) schließt, funktioniert es jetzt wie vorgesehen.
Momentan auch ohne das RDConsole.exe im Autostart des Remoterechners eingebunden wird.
Welche Aufgabe hat dieses Script ursprünglich? …denn die RDState.txt wird ja bereits auf dem gemeinsamen Netzlaufwerk erzeugt, wenn RDStatecheck.exe ausgeführt wird.
Danke Heiko
Die RDConsole.exe ist dazu da, Konsolen-Sitzungen in die Status-Datei einzutragen. Es könnte ja sein, das jenseits von RDP mal jemand direkt am Rechner sitzt oder via KVM-Switch, TeamViewer/pcvisit, VNC, usw. direkt mit der Konsolensitzung verbunden ist.
Hallo Andy,
ok das macht natürlich Sinn.
Vielen Dank
Hallo Andy,
die Abfrage ob Konsolensitzung ja/nein mit RDConsole.exe funktioniert leider nicht.
Die Datei RDState.txt wird nicht erstellt, weil die Abfrage des Eintrages für SESSIONNAME aus der Registry nicht richtig erfolgt.
-> $sessionname = RegRead(“HKCUVolatile Environment”, “SESSIONNAME”)
Aktuell unter W10prox64 lautet der Keypfad HKCUVolatile Environmentxxx
xxx ist nach jeder Neuanmeldung anders; mal3 mal 5 mal 6
Kann man hier einen Platzhalter nutzen? Wie?
und müsste die Datei RDState.txt dann nicht auf das gemeinsame Netzlaufwerk (s:) geschrieben werden?
– $file = FileOpen(“S:RemotecheckRDState.txt”, 2)
Dann würde das Script “RDStateCheck.exe” deren vorhandensein auch melden -oder?
Danke für Deine Zeit
Heiko
> Aktuell unter W10prox64 lautet der Keypfad HKCUVolatile Environmentxxx
Stimmt. wie bereits erwähnt, die Lösung hat schon ein paar Jahre auf dem Buckel.
> Kann man hier einen Platzhalter nutzen? Wie?
Gute Frage, muss ich mal schauen, wie man das machen könnte bzw. “xxx” scheint mir die Session-ID zu sein.
Ich hab’ da auch schon eine Idee, muss das aber erstmal testen.
> und müsste die Datei RDState.txt dann nicht auf das gemeinsame Netzlaufwerk (s:) geschrieben werden?
Ja, deswegen steht ja auch im Beitrag “Die Datei RDConsole.exe in den Autostart des “RDP-Servers” verknüpfen.”
Gemeint ist, das die RDPConsole.exe vom Netzlaufwerk/UNC-Pfad aus in den Autostart verknüpft wird und NICHT die Exe-Datei auf dem Computer abgespeichert wird.
Dann passt das auch, das die Status-Datei am richtigen Ort geschrieben wird.
Hallo Andy,
jetzt hab ich das verstanden.
Habe derweil einen möglichen Lösungsansatz im Netz gefunden, weiss jedoch nicht,
wie ich den in das Script einbinden muss.
https://www.autoitscript.com/forum/topic/187569-unable-to-envgetsessionname/
>>Snap ON
Func _RegSessionName()
Local $i = 1, $sRegRoot = “HKCUVolatile Environment”, $sRegKey, $sRegVal = “”
While 1
$sRegKey = RegEnumKey($sRegRoot, $i)
If @error Then ExitLoop
$sRegVal = RegRead($sRegRoot & “” & $sRegKey, “SessionName”)
If $sRegVal “” Then Return $sRegVal
$i += 1
WEnd
Return “”
EndFunc
<<Snap OFF
Geht auch rein mit Batch:
@echo off
rem Konsolen-Sitzung abfragen
query session | find /i “console” > session.txt
rem Die Session-ID der Konsole ermitteln
set /p ID= NUL 2>&1
if %errorlevel% equ 0 (
echo Verbunden seit %time% am %date% > RDState.txt
echo von Computer: %SESSIONNAME% >> RDState.txt
)
del /q session.txt > NUL 2>&1
Datum und Uhrzeit sind in der Form nicht gleich formatiert wie bei der AutoIt-Lösung. Das ließe sich noch umsetzen. Das ist jetzt nur eine schnelle Lösung.