GUI to log off Remote Desktop users by non-admins

I’ve blogged about the issues with the well-intentioned but ill-though-out Remote Desktop Management Server concept in Windows Server 2012 (inc R2) before, trying to come up with workarounds to all the things you used to be able to do easily with tsadmin in previous version, that you now just cannot do.

Like delegate non-admin users (e.g. helpdesk, expert users) the ability to log off other users.

So here’s a PowerShell script that falls back on the (very) old but thankfully still perfectly functional quser and logoff commands. My suggestion is to create a group, put the helpdesk users who need this functionality into the group, then grant the group permission via the following command:

wmic /namespace:\\root\CIMV2\TerminalServices PATH Win32_TSPermissionsSetting WHERE (TerminalName ="RDP-Tcp") CALL AddAccount "domain\group",2

You need to run that on all your RDS servers.

Once the helpdesk staff are in the group they’ll need to log off the RDS server and back on again. Now you can give them the script to run.

The script uses quser to get the current user sessions on the server where it’s being run, parses it and displays it in a GridView (with multi-select). Selected users are then logged off via the (also old) logoff Command.
Get your helpdesk user to right-click the script, select “Run with PowerShell”, then just select one or more users to log off and click “OK”.

# Log off RDS user sessions
# For regular users to be able to do this you need to grant them permission:
# wmic /namespace:\\root\CIMV2\TerminalServices PATH Win32_TSPermissionsSetting WHERE (TerminalName ="RDP-Tcp") CALL AddAccount "domain\group",2

# Get the list of users using good old quser (query user)
$QUser = &quser.exe
# Get rid of the Sessionname column because it is inconsistent (contains no data for disconnected sessions)
$QUser = $QUser -replace("rdp-tcp#\d+","")
# Remove header row
$QUser = $QUser -replace("username.+time","")
# Tidy up the spaces to leave one space separator only
$QUser = $QUser -replace("\s+"," ")
# Remove the current user line prefix
$QUser = $QUser -replace(">"," ")
# Split into an array, data starts at position 3, 7 items per line
$QUserArray = $Quser -split " "
# Make an array of objects
$CurrentUsers = New-Object System.Collections.ArrayList
for ($i = 3; $i -lt $QUserArray.Count; $i+=7){
    $ThisUser = New-Object -TypeName System.Object
    Add-Member -InputObject $ThisUser -MemberType NoteProperty -Name "UserName" -Value $QUserArray[$i]
    Add-Member -InputObject $ThisUser -MemberType NoteProperty -Name "ID" -Value $QUserArray[$i+1]
    Add-Member -InputObject $ThisUser -MemberType NoteProperty -Name "State" -Value $QUserArray[$i+2]
    Add-Member -InputObject $ThisUser -MemberType NoteProperty -Name "IdleTime" -Value $QUserArray[$i+3]
    Add-Member -InputObject $ThisUser -MemberType NoteProperty -Name "LogonTime" -Value ($QUserArray[$i+4]+" "+$QUserArray[$i+5])
    $CurrentUsers.Add($ThisUser) | Out-Null
}
# Display the array in a gridview
$SelectedUsers = $CurrentUsers | Out-GridView -Title "Select users(s) to log off" -OutputMode Multiple
# Log off selected sessions
foreach($User in $SelectedUsers){
    Write-Host ("Logging off "+$User.UserName+" (session ID "+$User.ID+")... ") -NoNewline
    $x = &logoff.exe $User.ID
    Write-Host "Done"
}
Start-Sleep -Seconds 1
Advertisements
This entry was posted in PowerShell, Remote Desktop, Windows and tagged , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s