<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1678611822423757&amp;ev=PageView&amp;noscript=1">
Defrag This

| Read. Reflect. Reboot.

How To Log Off Windows Users Remotely With PowerShell

Adam Bertram| December 12 2018

| IT insights, PowerShell, Scripting

how-to-log-off-windows-users-remotely-with-powershell

Here is a quick and easy way to remotely log off end users who are still logged into their computers. This is especially useful when you are trying to do maintenance.

End users are sometimes logged into their computers for far too long. It seems like every time you’d like to do some maintenance on the computer that requires a user logging out, they don’t seem to do it or the computer is idling with them logged in! Luckily, we can take this into our own hands by forcing a logoff remote from another computer.

Using PowerShell, we can create a script that reaches out to one or more remote Windows computers, checks to see if anyone is logged in and, if so, logs them out. We can even log off all users if we so desire.

Before we get too crazy though, we first need to figure out how to find which users are logged into a remote computer. There are a few ways to do that but I’ve chosen to use the quser command. This is a non-PowerShell command but we can still just as easily use it from within PowerShell.

You can play around with this command by running it locally on your Windows computer to get an idea of the output.

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

However, we’ll be using PowerShell to parse this string output so you don’t have to worry about it in the first place!

The quser command also can query remote computers using the /server switch, however, I have chosen not to use this method because we now have the advantage of using PowerShell Remoting. Instead, we can run quser by itself on the remote computer.

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

Now that you know of how to find the logged in users, we now need to figure out how to log off a user. I’ve chosen to use the logoff command. The logoff command is another non-PowerShell command, but is easy enough to call from within a script.

In the example above, 'abertram' is logged into the remote computer in session 2. Using the logoff command, we simply need to pass the session ID to the command as an argument and it will dutifully log the user off as expected.

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

I can run quser again on the remote computer and we can now see that it has been logged off.

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

We now need to put these two commands together to allow us to specify a username rather than a session ID to log off a user account. To do that, we need to run quser, filter the output by username and then parse the session ID from that output sending it to the logoff command.

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

You can see above when Invoke-Command is running with the scriptblock created, it will detect the user logged in and immediately log them off. Pretty cool!

Topics: IT insights, PowerShell, Scripting

Leave a Reply

Your email address will not be published. Required fields are marked *

THIS POST WAS WRITTEN BY 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.

Free Trials

Getting started has never been easier. Download a trial today.

Download Free Trials

Contact Us

Let us know how we can help you. Focus on what matters. 

Send us a note

Subscribe to our Blog

Let’s stay in touch! Register to receive our blog updates.