So können Sie Windows-Benutzer per Fernzugriff mit PowerShell abmelden

Februar 03, 2019 Sicherheit und Compliance, MOVEit

Nachstehend ist eine schnelle und einfache Möglichkeit für die Remote-Abmeldung von Endbenutzern beschrieben, die auf Ihren Computern angemeldet sind. Diese Option ist besonders hilfreich, wenn Sie Wartungsarbeiten ausführen möchten.

Endbenutzer sind manchmal viel zu lange auf Ihren Computern angemeldet. Wenn Wartungsarbeiten auf einem Computer ausgeführt werden sollen, bei denen der Benutzer abgemeldet sein muss, dann ist es ein Problem, wenn der Benutzer noch angemeldet ist oder der Computer inaktiv ist, während der Benutzer weiterhin angemeldet ist. Glücklicherweise können wir in solchen Fällen per Fernzugriff eine Abmeldung von einem anderen Computer erzwingen.

Mit PowerShell können wir ein Skript erstellen, das einen oder mehrere Windows-Remote-Computer kontaktiert, überprüft, ob jemand angemeldet ist, und diese(n) Benutzer gegebenenfalls abmeldet. Wir können sogar alle Benutzer abmelden, wenn wir dies möchten.

Bevor wir uns damit weiter befassen, müssen wir herausfinden, welche Benutzer auf einem Remote-Computer angemeldet sind. Um das umzusetzen, gibt es einige Möglichkeiten. Ich habe mich für den quser-Befehl entschieden. Das ist kein PowerShell-Befehl, kann aber dennoch in PowerShell verwendet werden.

Sie können den Befehl testen, um eine Vorstellung darüber zu erhalten, welche Ausgabe er generiert, indem Sie ihn lokal auf Ihrem Windows-Computer ausführen.

PS> quser
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>administrator         console             1  Active      none   9/22/2018 11:04 AM

Auch wenn es kein PowerShell-Befehl ist, verwenden wir dennoch PowerShell, um die Ausgabe der Zeichenkette zu analysieren.

Mit dem quser-Befehl können auch Remote-Computer mithilfe des Server-Switch abgefragt werden. Ich habe mich allerdings gegen diese Methode entschieden, weil wir jetzt den Vorteil haben, PowerShell-Remoting zu verwenden. Wir können stattdessen den quser-Befehl alleine auf dem Remote-Computer ausführen.

PS> Invoke-Command -ComputerName 'REMOTECOMPUTER' -ScriptBlock { quser }
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
 abertram              rdp-tcp#7           2  Active          7  9/26/2018 4:57 PM

Nachdem Sie erfahren haben, wie Sie angemeldete Benutzer finden, beschäftigen wir uns nun damit, wie Benutzer abgemeldet werden. Ich habe mich dafür entschieden, den logoff-Befehl zu verwenden. Der logoff-Befehl ist auch kein PowerShell-Befehl, lässt sich aber einfach in einem Skript aufrufen.

In dem Beispiel oben ist 'abertram' am Remote-Computer in Sitzung 2 angemeldet. Mithilfe des logoff-Befehls müssen wir einfach nur die Sitzungs-ID als Argument an den Befehl weitergeben. Dann wird der Benutzer wie erwartet abgemeldet.

PS> Invoke-Command -ComputerName 'REMOTECOMPUTER' -ScriptBlock { logoff 2 }

Ich kann den quser-Befehl erneut auf dem Remote-Computer ausführen und jetzt sehen wir, dass die Abmeldung erfolgt ist.

PS> Invoke-Command -ComputerName 'REMOTECOMPUTER' -ScriptBlock {quser}
No User exists for *
    + CategoryInfo          : NotSpecified: (No User exists for *:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
    + PSComputerName        : REMOTECOMPUTER

Wir müssen diese beiden Befehle jetzt zusammen verwenden, damit wir zum Abmelden eines Benutzerkontos statt einer Sitzungs-ID einen Benutzernamen festlegen können. Dafür müssen wir den quser-Befehl ausführen, die Ausgabe nach Benutzernamen filtern, die Sitzungs-ID aus dieser Ausgabe analysieren und diese dann an den logoff-Befehl senden.

$scriptBlock = {
    $ErrorActionPreference = 'Stop'

    try {
        ## Find all sessions matching the specified username
        $sessions = quser | Where-Object {$_ -match 'abertram'}
        ## Parse the session IDs from the output
        $sessionIds = ($sessions -split ' +')[2]
        Write-Host "Found $(@($sessionIds).Count) user login(s) on computer."
        ## Loop through each session ID and pass each to the logoff command
        $sessionIds | ForEach-Object {
            Write-Host "Logging off session id [$($_)]..."
            logoff $_
        }
    } catch {
        if ($_.Exception.Message -match 'No user exists') {
            Write-Host "The user is not logged in."
        } else {
            throw $_.Exception.Message
        }
    }
}

## Run the scriptblock's code on the remote computer
PS> Invoke-Command -ComputerName REMOTECOMPUTER -ScriptBlock $scriptBlock

Found 1 user login(s) on computer.
Logging off session id [rdp-tcp#10]...

Wie an den obigen Angaben zu erkennen ist, geschieht Folgendes: Wenn der Invoke-Befehl mit dem erstellten ScriptBlock ausgeführt wird, wird der angemeldete Benutzer erkannt und umgehend abgemeldet!

Tipp: Lesen Sie dazu auch das Whitepaper Automatisieren mit PowerShell oder laden Sie sich kostenfrei eine Testversion von MOVEit Automation, Software für die Automatisierung der Dateiübertragung, herunter.

Adam Bertram

 

Adam Bertram ist seit 20 Jahren in der IT-Branche tätig und arbeitet aktuell als Automatisierungs-Ingenieur, Blogger und selbstständiger Consultant und Autor, und Ausbilder. Sein Schwerpunkt liegt dabei auf DevOps, System-Management und Automatisierungs-Technologien, sowie auf zahlreichen Cloud-Plattformen. Er ist ein Microsoft Cloud und Datacenter Management MVP und ist dafür bekannt effizient zu arbeiten. Außerdem liebt er es anderen Leuten die Welt der Automatisierung näherzubringen.

Read next Benutzung der neuen MOVEit 2018 REST API mit PowerShell