Comment déconnecter les utilisateurs Windows à distance avec PowerShell

février 03, 2019 Sécurité et conformité, MOVEit

Voici un moyen rapide et simple de déconnecter les utilisateurs dont les sessions sont toujours ouvertes sur leurs ordinateurs. Ce procédé est particulièrement utile lorsque des opérations de maintenance sont nécessaires.

Parfois les utilisateurs sont connectés à leurs ordinateurs trop longtemps sans raison. Il semble que chaque fois que vous souhaitez intervenir sur des ordinateurs dont les utilisateurs doivent être déconnectés, ces derniers n’ont pas respecté la consigne ou bien l’ordinateur tourne au ralenti avec une session ouverte. Heureusement, nous pouvons prendre la main via une fermeture forcée des sessions à partir d’un autre ordinateur.

Avec PowerShell, il est possible de créer un script qui atteint un ou plusieurs ordinateurs Windows distants, vérifie si des sessions sont ouvertes et, si tel est le cas, les ferme. Nous pouvons même déconnecter tous les utilisateurs si nécessaire.

Toutefois, pour éviter de faire n’importe quoi, il est d’abord nécessaire d’identifier les utilisateurs connectés à un ordinateur distant. Il y a plusieurs moyens d’y parvenir, mais j’ai choisi d’utiliser la commande quser. Il est possible d’exécuter une commande non-PowerShell, mais la commande PowerShell est tout aussi simple.

Vous pouvez tester cette commande en l’exécutant en local sur votre ordinateur Windows pour vous faire une idée du résultat.

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

Nous utiliserons PowerShell cependant pour analyser cette chaîne en sortie, donc pas d’inquiétude !

La commande quser permet également d’interroger des ordinateurs distants via le commutateur /server ; toutefois, j’ai choisi de ne pas utiliser cette méthode car nous avons aujourd’hui l’avantage d’utiliser des sessions PowerShell distantes. Au lieu de cela, quser peut être exécuté en propre sur l’ordinateur distant.

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

Maintenant que vous savez comment identifier les utilisateurs connectés, nous devons voir comment déconnecter un utilisateur. J’ai choisi d’utiliser la commande logoff. La commande logoff est une autre commande non-PowerShell qui peut être appelée simplement à partir d’un script.

Dans l’exemple ci-dessus, « abertram » est connecté à l’ordinateur distant dans la session 2. À l’aide de la commande logoff, nous devons simplement transmettre l’ID de session à la commande comme argument et elle déconnectera l’utilisateur comme attendu.

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

Je peux à nouveau exécuter la commande quser sur l’ordinateur distant et nous constatons maintenant qu’il est déconnecté.

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

Nous devons ensuite regrouper ces deux commandes pour nous permettre d’indiquer un nom d’utilisateur plutôt qu’un ID de session pour déconnecter un compte utilisateur. Pour ce faire, nous devons exécuter quser, filtrer le résultat par nom d’utilisateur, puis analyser l’ID de session dans ce résultat en l’envoyant à la commande logoff.

$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]...

Vous pouvez voir ci-dessus que lorsque la commande Invoke s’exécute et que le scriptblock est créé, il détecte l’utilisateur connecté et le déconnecte immédiatement. Génial !

Adam Bertram

Adam Bertram is a 20-year veteran of IT. He’s currently an automation engineer, blogger, independent consultant, freelance writer, author, and trainer. Adam focuses on DevOps, system management, and automation technologies as well as various cloud platforms. He is a Microsoft Cloud and Datacenter Management MVP and efficiency nerd that enjoys teaching others a better way to leverage automation.

Read next Utilisation de la nouvelle API REST de MOVEit 2018 avec PowerShell