Log off multiple users on a schedule with PowerShell

The PowerShell script discussed in this post allows you to log off multiple users on multiple computers.

One of the issues when performing tasks like deploying software or making user-based configuration changes is dealing with interactive logons. We try to avoid it, but sometimes we have to force users to log off the machine to apply the changes we need. The normal procedure is to blast out an email a day before reminding them of this, but ultimately, there's always at least 30% of users that don't see the reminder or just forget. We need a way to force this behavior when we need to, and on a schedule. We can use PowerShell.

One of the first tasks you'll need to figure out is how to force a logoff of multiple users on multiple computers at once. We're obviously not going to sneakernet this! There are a few ways to do this, but I've created a small PowerShell script to make it easy. You can download it from the PowerShell Gallery via: Install-Script -Name Invoke-UserLogoff. Once you've downloaded the script, find it at C:\Program Files\WindowsPowerShell\Scripts\Invoke-UserLogoff.ps1.

Using the Invoke-UserLogoff.ps1 script is straightforward. It has two parameters: ComputerName and UserName; both are optional. To log off a user called abertram on the remote computer CLIENT1, I can invoke the script like this:

PowerShell logs off a user

PowerShell logs off a user

To log off all the users on the CLIENT1 computer, I can simply omit the UserName parameter.

You can also feed lots of computers at once to this script by adding them as comma-separated values to the ComputerName parameter like so:

Now that we've got a tool that can remotely log off users, we now need to figure out how to invoke this on a schedule. Perhaps we've got a maintenance window coming up and we'd rather just run this right beforehand so that we know all the users are logged off. Because we're all about PowerShell and automation, there's no need to create this scheduled task manually! Let's create it properly using another script called New-ScheduledScript.ps1, again freely available in the PowerShell Gallery.

Since we're going to be scheduling this script, we need a way to feed the user logoff script a set of computer names. We can do this several ways, but the easiest would probably be creating a text file full of computer names and placing it on the server that your scheduled task will run on. For my example, I'm going to create a file called computers.txt and place it on the root of the C: drive on the server I'll be creating the scheduled task on; I'll call that server SRV1. While I'm at it, I'll also copy the Invoke-UserLogoff.ps1 script to SRV1 in the same location. We'll need to invoke this script in our scheduled task.

We should now have two files at \\SRV1\c$\computers.txt and \\SRV1\c$\Invoke-UserLogoff.ps1. If so, it's time to build the tiny script we'll be executing that will actually perform the action we're after. This tiny script will just bring together the computers in computers.txt with the Invoke-UserLogoff script. It looks something like this:

I'll call this script Invoke-MaintenanceWindowLogoff.ps1 and for now just put it in the root of C: on my local computer. Once I do that, I'll have everything set up. I can now go back to my local computer and execute New-ScheduledScript.ps1 to create the scheduled task that invokes the Invoke-MaintenanceWindow.ps1 script and actually performs the logoffs.

Here's an example of how we could run it:

Refer to the help content for New-ScheduledScript.ps1 for more information.

By now, you should have a scheduled task named DailyMaintenanceLogoff on SRV1 that's executing the C:\Invoke-MaintenanceWindow.ps1 script! The last task to perform is to test it out!

2+
avataravatar

Join the 4sysops PowerShell group!

Your question was not answered? Ask in the forum!

7 Comments
  1. Nigel 3 years ago

    How about a features to log off all found computers except ones in list, also a re boot option as well.

    0

  2. Brent 3 years ago

    This fails for me when no users are logged in - the script errors out with:

    quser : No User exists for *
    At C:\Program Files\WindowsPowerShell\Scripts\Invoke-UserLogoff.ps1:71 char:20
    + if ($sessions = ((quser $compArgs | Where-Object $whereFilter))) ...
    + ~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (No User exists for *:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

    Which breaks things.  I'd like to log out any server with local logins, but most won't have one.  I'm going to do a dirty workaround by catching these and going on, but I wanted to let you know 🙂

    0

  3. mehmet 2 years ago

    Hello,

    Where can I find this Invoke-UserLogoff.ps1.?

    Do you have download link.?

    Please, Can you help me.

    Thanks.

    0

  4. Lukas 2 years ago

    We get an error message "Session SESSIONNAME not found" when we omit the -username parameter. 

    Any suggestions?

     

    thx

    4+

    • With my limited testing, I could simulate the error. I guess the script needs some patchwork to loop through sessions array and then process on individual sessionIds. 

      if ($sessions = ((quser $compArgs | Where-Object $whereFilter))) {

              $sessionIds = ($sessions -split ' +')[2]

      0

    • John Morris 5 months ago

      I'm having the same issue as Lukas

      2+

  5. Arpit 3 months ago

    Hi Adam,

    We get an error message "Session SESSIONNAME not found" when we omit the -username parameter. 

    Any suggestions?

    Thank you

    0

Leave a reply

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

*

© 4sysops 2006 - 2020

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account