8

Is there a powershell command I can use to kick "disconnected" users off a server? I can write the script once I know the single line to kick a single user.

For example, I want to kick the 8 users seen in the dialog below.

enter image description here

user952342
  • 2,602
  • 7
  • 34
  • 54

4 Answers4

9

I can't try this:

$pc = qwinsta /server:YourServerName | select-string "Disc" | select-string -notmatch "services"

if ($pc)
{
  $pc| % { 

  logoff ($_.tostring() -split ' +')[2] /server:YourServerName 

  }
}
CB.
  • 58,865
  • 9
  • 159
  • 159
  • I use this locally in a 'kiosk-like' server for an IT departement ( a long story) and it works. Never tested remotely, but I think can work, me too. – CB. Jan 17 '13 at 19:57
  • @C.B-I recently ran into the same issue where i need to logOff all the disconnected users..So can you say me how to implement this and where as recently I have a asked same question here http://stackoverflow.com/questions/18377592/get-disconnected-users-and-logoff-them ? – coder Aug 22 '13 at 10:39
5

In my opinion, the easiest way would be to use logoff.exe that already exists on your machine. for instance to log off the first disconnected user in your screenshot:

logoff 3 /server:YOURSERVERNAME
EBGreen
  • 36,735
  • 12
  • 65
  • 85
2

Here's a great scripted solution for logging people out remotely or locally. I'm using qwinsta to get session information and building an array out of the given output. This makes it really easy to iterate through each entry and log out only the actual users, and not the system or RDP listener itself which usually just throws an access denied error anyway.

$serverName = "Name of server here OR localhost"
$sessions = qwinsta /server $serverName| ?{ $_ -notmatch '^ SESSIONNAME' } | %{
$item = "" | Select "Active", "SessionName", "Username", "Id", "State", "Type", "Device"
$item.Active = $_.Substring(0,1) -match '>'
$item.SessionName = $_.Substring(1,18).Trim()
$item.Username = $_.Substring(19,20).Trim()
$item.Id = $_.Substring(39,9).Trim()
$item.State = $_.Substring(48,8).Trim()
$item.Type = $_.Substring(56,12).Trim()
$item.Device = $_.Substring(68).Trim()
$item
} 

foreach ($session in $sessions){
    if ($session.Username -ne "" -or $session.Username.Length -gt 1){
        logoff /server $serverName $session.Id
    }
}

In the first line of this script give $serverName the appropriate value or localhost if running locally. I use this script to kick users before an automated process attempts to move some folders around. Prevents "file in use" errors for me. Another note, this script will have to be ran as an administrator user otherwise you can get accessed denied trying to log someone out. Hope this helps!

Jason Slobotski
  • 1,386
  • 14
  • 18
  • Tried this and it did not work for me. In fact it only disconnected a couple of users. I am guessing that I need to switch "Active" to "Disconnected"? – BanjoFox Jan 27 '20 at 14:55
  • I don't think so. "Active" is just the header definition for the array being built. That doesn't actually have anything to do with the array's contents. I would start by logging what it actually found and adjust things from there to meet your specific needs. Also if qwinsta's output has changed since I wrote this then the substring commands may need to be adjusted. – Jason Slobotski Jan 27 '20 at 22:10
  • Solution would be a lot cleaner if you used the result of `qwinsta /server $serverName` as an object instead of hoping your substring gets the right parts back. Perhaps there's a powershell Core function that does the same thing? – Kellen Stuart Sep 08 '21 at 18:38
1

Here you go:

@echo off
(set STATE=Disconnected)
REM !! IMPORTANT set length in 4th from last line !!

FOR /f "Skip=1 tokens=3,4" %%i in ('qwinsta') do (
IF /I NOT "%%i"=="The" (
call :checkpath %%i "%%j"
)
)
::pause
GOTO :EOF

:checkpath
set id=%1
set STATUS=%~2
:: !! The last number in the next line needs to
:: be the length of the STATE string

SET root=%STATUS:~0,12%
IF /I NOT "%ROOT%"=="%STATE%" GOTO :EOF
@echo on
Session ID %ID% is %STATUS%. Logging off...
@echo off
logoff %ID% /server:YOURSERVERNAME
Demish Alex
  • 81
  • 1
  • 1
  • Good answer! Could you further explain what a few of the variables, such as STATUS are representing? – Jimmy Smith Sep 29 '14 at 17:56
  • 1
    STATE - value to look for (Disconnected); STATUS - Value of the state brought by qwinsta; id - value of ID brought by wqinsta; ROOT - is first 12 characters of STATUS – Demish Alex Sep 29 '14 at 18:58
  • 1
    Originally this script was used to close open files by directory, so for the current task some of the things really doing nothing – Demish Alex Sep 29 '14 at 19:00