How to Query and Log Off Remote Desktop Sessions with Powershell

The Remote Desktop Procotol (RDP) is still strong and it’s not going away anytime soon, indeed there are companies like CITRIX that have built part of their success creating robust management for it.
As you can Imagine, there a lot of ways to manage RDP according to the type of implementations or tools involved, so some corner cases will not be cover in this article. There are also tools like gateways that will provide a central management point for all sessions, but let’s assume that these tools are not available to you or not part your infrastructure design.

Today,  I will show you some of the available tools that we can use to manage a common issue like listing all “Disconnected RDP sessions” on your network from the CLI, every tool that have a GUI is out of scope in this case.

You can easily realise why, if you want to create a report of all the disconnected sessions on hundreds of servers I don’t think that you want to log into each server to find out what are the connections and their state (active or disconnected), right?

Let’s start with the obvious statement that scripting can’t resolve all your issues, but for sure will help you to understand it sooner than later if you’ve got one!

If you want to get rid of all disconnected sessions from some of your servers or similar issues could be mitigated by automation, but scripting alone will not help you to solve it at scale. Sometimes the best way to solve it can involve GPOs, Configuration Management or sometimes third-party solutions.

But let’s start with gathering some information from all our network querying AD for all computer part of the TEST project :

Query Session / Qwinsta

Windows offers from the cmd-prompt the ability to query all sessions from the local or remote machine with this command:

Or qwinsta (which is exactly the same).

Get-RemoteRdpSession

The script that I wrote is basically a wrapper that accepts a list of computer names returns a DataTable object that could be filtered, exported and so on…

With this new function after importing it with the dot-sourcing we can get a list of all computers with an Active RDP Session :

The main goal of having this DataTable object is that now the result can be filtered.

I haven’t found anything similar on powershell gallery or any other module, so I was considering to do it myself. If you would like to have it on powershell gallery or part of a module please write a comment and I will spend some time to do it.

How to log off all disconnected sessions

Or log off all the disconnected RDP session found:

The benefit of gathering this type of data is that you can soon realise that you need to create a GPO to auto-logoff after a reasonable amount of hours, for instance, 3 hours, all disconnected sessions from a group or all servers.

As query session has qwinsta, logoff has rwinsta.

For this and other commands regarding the Remote Desktop Session, I strongly recommend having a look at the official documentation. 

I hope that you find this script interesting, as always this source code is available on my github repository.

10 Replies to “How to Query and Log Off Remote Desktop Sessions with Powershell”

  1. When I execute this I get no output, it just returns back to the command prompt. I’m executing this:

    .\Get-RemoteRdpSession -computername (“servername_goes_here”, “servername_goes_here”) -state DISC

    Thanks for any assistance!

    1. Hi Pat,
      Are you using the dot-sourcing method to import the function first?

      The function Get-RemoteRdpSession needs to defined before invoking it if you define you Get-RemoteRdpSession on your Get-RemoteRdpSession.ps1 script you need to “import it” first
      . .\Get-RemoteRdpSession.ps1

      Then you can re-run your command. Have a look at this article https://www.scriptinglibrary.com/languages/powershell/powershell-dot-sourcing/
      If I haven’t properly understood your problem or context, sorry for that.
      Regards

      1. Thanks Paolo, that cleared it up and I was able to execute the script. My new question would be that no matter what I seem to enter in for -computername the only response I ever get back “No session exists for*”

        1. Hi Patrick,
          Get-RemoteRdpSession is a wrapper of query session / qwinsta so that message is not coming from the powershell script, but from query session command instead. I guess that you get that message because your user doesn’t have enough rights on the remote server.
          If your user is a member of the local admin group on the remote server it should not have any problem to retrieve this information. To troubleshoot this you can run query session /server:SERVERNAME and I guess you’ll have the message you’ve mentioned. If you add your user to the local administrator group on the target server or run this script with a user that is already in that group… then everything should work as expected.
          I hope this is going to help you to solve your problem.
          Regards

    1. Hi David,
      Thanks for your comment. Interesting question. I don’t know off top of my head.. I doubt that information is available via query session. The closest information to the IP is the ClientName that you can also get it from task manager/users and adding the client name field.
      To get it via the CLI a way to get that info maybe is to extract the logon (6424) event from the security log.. but again it will be not easy to extract the entry where you have the IP.
      If there is just one connection a simple netstat -at | findstr 3389 will show the ip and you can use invoke-command against the target endpoint to query that information remotely.

      Thanks,
      Regards

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.