List RDP Sessions on Remote Servers in PowerShell

Posted On 2016-02-17 by dwirch
Tags: Powershell Scripting Windows Windows Server 2008 Windows Server 2012
Views: 8355

You can use this handy little script to find remote desktop sessions on all servers running in your Active Directory domain.

It's a fact of life as a sysadmin.  You RDP to a machine, leave a task running, and disconnect. Invariably, you forget that session, and it sits their disconnected. Being a good admin, there is a password policy that requires you to change your password every 90 days.  The time comes, and you change your password, as required.

Bam. Your account is locked out. Now you get to go find all those abandoned sessions, running under your old credentials.  Good times.  Wouldn't it be handy if you could simply run a script to find all your dead sessions?

We've all used the query session command to get a list of sessions on a remote server, then use the logoff command to remotely log off any dead sessions.  If you haven't you can read up on it here: Killing Disconnected Terminal Server Sessions from the Command Line.

The general flow of the script is thus:

  • Import the Active Directory module (required), and set some variables.
  • Get a list of servers from Active Directory. I've included three methods of getting a list of machines in the script (two from AD, one from a file) within the script.
  • Iterate through the list with a ForEach loop, running qwinsta.exe against each host. This produces the same output as the query session command.
  • Parse the output of the qwinsta command.  In this script, the data seems to change places (my opinion, anyway), hence the hodgepodge of logical ANDs and whatnot.
  • Present the output to the user.

I've pasted the script below, and I hope someone gets some use out of this. As always, if you have any questions, comments, or concerns regarding this, drop a note in the comments, or start a thread in the forums. It'd be super cool if someone could improve upon this!

# import the active directory module

import-module activedirectory

# set some variables

$SessionList="`n`nRDP Session List - " + $Today + "`n`n"

# Get a list of servers from Active Directory. Note that two different strings have been
# given. The first one will get all servers in Active Directory, while the second one
# (which is commented) will target all hosts in a particular OU.  The third option is
# for grabbing a list of machines (one per line) from a file.

write-progress -activity "Getting list of servers from Active Directory" -status "... please wait ..."

$Servers=get-adcomputer -filter {OperatingSystem -like "*server*"}
# $Servers=Get-adcomputer -filter * -searchbase "OU=servers,dc=dwlab02,dc=local"
# $Servers=Get-Content "c:\files\myfile.txt"


# Iterate through the retrieved list to check RDP sessions on each machine

ForEach ($Server in $Servers) {

    Write-progress -activity "Checking RDP Sessions" -status "Querying $ServerName" -percentcomplete (($CurrentSN/$NumberOfServers)*100)

    # Run qwinsta and grab the output

        $queryResults = (qwinsta /server:$ServerName | foreach { (($_.trim() -replace "\s+",","))} | convertfrom-csv)

        # get session info from the instance

        ForEach($QueryResult in $QueryResults) {

            If($ReturnedCurrentState -eq $null){ $CurrentState="Disconnected" } Else { $CurrentState="Active" }
            # filter out the chaff

            If (($RDPUser -ne $NULL) -and ($SessionType -ne "console") -and ($SessionType -ne "services") -and ($SessionType -ne "rdp=tcp") -and ($RDPUser -ne "65536")) {
                $SessionList=$SessionList + "`n" + $ServerName + " logged in by " + $RDPUser + " on " + $SessionType + ", session id $SessionID $CurrentState"

        $SessionList=$SessionList + "`n Unable to query " + $ServerName
        write-host "Unable to query $ServerName!" -foregroundcolor Red

# Send the output the screen.

$SessionList + "`n`n"

About the Author

dwirch has posted a total of 188 articles.

Comments On This Post

By: dwirch
Date: 2016-04-27

Watch out for line wrap in the script above!!

By: AnonymousCoward
Date: 2017-10-05


In order to get the try catch to work i needed to add ErrorAction

       $queryResults = (qwinsta /server:$ServerName | foreach { (($_.trim() -replace "\s+",","))} | convertfrom-csv -ErrorAction Stop)

Also is using computers from a txt file remove the .name


Do you have a thought relating to this post? You can post your comment here. If you have an unrelated question, you can use the Q&A section to ask it.

Or you can drop a note to the administrators if you're not sure where you should post.

Your IP address is:

Before you can post, you need to prove you are human. If you log in, this test goes away.

Code Links