9

Get Logged In Users Using Powershell

A while back I posted my initial script to find the users that are logged into a server and log them off remotely. That was several years ago and I thought I would take another crack at it to try to improve the speed, improve the formatting and add some dedicated switches with a bit more flexibility. Lastly, I wanted to change that ugly, unconventional name to something more Powershell approved. I call this new function Get Logged In Users.

 
The underlying structure is still going to be using query session so that hasn’t changed. What has changed is now we can specify a specific user or find where a user is logged on in a domain. Another note is the ability to log them off using a simple switch so that can definitely come in handy if you’re checking a log of systems.

Get Logged In Users Using Powershell

Looking back I don’t know why I added the ActiveDirectory Module and made it run as an administrator. That is simply not needed and not required to run this function. However, I would highly recommend you run this on a Windows 10 machine or Server 2016 and later with Powershell 5 because well let’s face it, we’re in 2020.

Parameters

    -ComputerName

Description: This will specify the ComputerName that you would like to check.  If no ComputerName is specified, it will check the local computer.

    -UserName

Description: If the specified username is found logged into a machine, it will display it in the output.

 


Function Get-LoggedInUser {
<#
.SYNOPSIS
    This will check the specified machine to see all users who are logged on.
    For updated help and examples refer to -Online version.

.NOTES
    Name: Get-LoggedInUser
    Author: Paul Contreras
    Version: 3.0
    DateUpdated: 2021-Sep-21

.LINK
    https://thesysadminchannel.com/get-logged-in-users-using-powershell/ -
    For updated help and examples refer to -Online version.

.PARAMETER ComputerName
    Specify a computername to see which users are logged into it.  If no computers are specified, it will default to the local computer.

.PARAMETER UserName
    If the specified username is found logged into a machine, it will display it in the output.

.EXAMPLE
    Get-LoggedInUser -ComputerName Server01
    Display all the users that are logged in server01

.EXAMPLE
    Get-LoggedInUser -ComputerName Server01, Server02 -UserName jsmith
    Display if the user, jsmith, is logged into server01 and/or server02


#>

    [CmdletBinding()]
        param(
            [Parameter(
                Mandatory = $false,
                ValueFromPipeline = $true,
                ValueFromPipelineByPropertyName = $true,
                Position=0
            )]
            [string[]] $ComputerName = $env:COMPUTERNAME,


            [Parameter(
                Mandatory = $false
            )]
            [Alias("SamAccountName")]
            [string]   $UserName
        )

    BEGIN {}

    PROCESS {
        foreach ($Computer in $ComputerName) {
            try {
                $Computer = $Computer.ToUpper()
                $SessionList = quser /Server:$Computer 2>$null
                if ($SessionList) {
                    $UserInfo = foreach ($Session in ($SessionList | select -Skip 1)) {
                        $Session = $Session.ToString().trim() -replace '\s+', ' ' -replace '>', ''
                        if ($Session.Split(' ')[3] -eq 'Active') {
                            [PSCustomObject]@{
                                ComputerName = $Computer
                                UserName     = $session.Split(' ')[0]
                                SessionName  = $session.Split(' ')[1]
                                SessionID    = $Session.Split(' ')[2]
                                SessionState = $Session.Split(' ')[3]
                                IdleTime     = $Session.Split(' ')[4]
                                LogonTime    = $session.Split(' ')[5, 6, 7] -as [string] -as [datetime]
                            }
                        } else {
                            [PSCustomObject]@{
                                ComputerName = $Computer
                                UserName     = $session.Split(' ')[0]
                                SessionName  = $null
                                SessionID    = $Session.Split(' ')[1]
                                SessionState = 'Disconnected'
                                IdleTime     = $Session.Split(' ')[3]
                                LogonTime    = $session.Split(' ')[4, 5, 6] -as [string] -as [datetime]
                            }
                        }
                    }

                    if ($PSBoundParameters.ContainsKey('Username')) {
                        $UserInfo | Where-Object {$_.UserName -eq $UserName}
                      } else {
                        $UserInfo | Sort-Object LogonTime
                    }
                }
            } catch {
                Write-Error $_.Exception.Message

            }
        }
    }

    END {}
}

 

How To Run Get Logged In User Powershell Script

In order to the run the script there are a couple of things you need to do.  First and foremost, you need to set your execution policy to RemoteSigned or bypass.  This is a standard with running any Powershell script.

Next you need to dot source the script since it is a function.  To dot source the script do the following:

  • Copy the script above and save it any location. In this example I’ll save it to my C:\_Scripts folder.
  • Within the Powershell Window type: . .\_Scripts\Get-LoggedInUser.ps1 – Note the two dots before the backslash.

 

Get Logged On Users On Remote Computers

The best thing I love about this script is your ability to get who is logged into a remote computer. This mitigates the need to physically log into computer and checking that way. Since this Powershell script allows you to query remote servers and computers, it makes it highly automatable and very scalable. Using this script, you can check 1 server or 1,000 servers and it would be the same amount of effort for the person who is running it. It’s awesome and I love how you can do it all from your own Windows 10 computer.

You can also find where a user is logged on in a domain very easily. Depending on how many machines you’re going to be iterating through, it can obviously take some time but it can be done. Here is a simple code snippet of how to get where a user is logged in to.

PS C:\> . .\_Scripts\Get-LoggedInUser.ps1
PS C:\>
PS C:\> Get-LoggedInUser -ComputerName PAC-WIN1001, PAC-ADC01, PAC-DC01
 
ComputerName UserName   SessionState LogonTime
------------ --------   ------------ ---------
PAC-WIN1001  pcontreras Active       8/5/2021 10:00:00 PM
PAC-ADC01    pcontreras Disconnected 6/22/2021 7:27:00 AM
PAC-DC01     pcontreras Disconnected 6/22/2021 4:29:00 PM

Get-Logged In User

 

Conclusion

So there you have it, a quick and easy solution to a problem that many IT Administrators have come across in their sysadmin journey. I am well aware that you can also do this via group policy if you wanted to go that route, or you can do this via some GUI tool but I always like to get my hands dirty with Powershell.

Thanks again for taking the time to visit and go ahead and drop a comment if you have any questions about the script or its intended fuctions. Also, don’t forget to check out our Youtube Channel for visual video content and our own personal Powershell gallery full of real world scripts.

5/5 - (20 votes)

Paul Contreras

Hi, my name is Paul and I am a Sysadmin who enjoys working on various technologies from Microsoft, VMWare, Cisco and many others. Join me as I document my trials and tribulations of the daily grind of System Administration.

9 Comments

  1. Hi Mr Paul, is it possible that when I run the script on server A, it automatically reads the logged-on server A’s user and display it right away?

  2. Hi Paul
    Nice script, for me however, each object is getting listed 1 after the other, opposed to in tabular format, do you know why? (Windows 10, Powershell version 5.1)
    Is it possible to get the output to be emailed on a daily schedule?
    Thanks in advance

      • Thanks for the response
        I have a few other scripts that I use to generate html email reports with the output embedded in the body of the email and nicely formatted using ConvertToHtml and -Fragment.
        I have used that along with your script and the output in the email is in tabular form which is exactly what I wanted so much appreciated, this is now scheduled at the start and end of the working day. I also have emails firing for logon event id 4624 and RDP Logon Type 10 so I know every time a user RDP’s onto the Servers.
        When I run your script directly from Powershell however as mentioned it still lists the objects opposed to being tabular and I am not sure why but it is not a problem because I only run this against 11 Servers I admin.

        Regards

  3. Paul
    Not one to post, but i just had to. Coz its awesome work AND pretty neat (very structured and clean) too!
    Thank you!

  4. This doesn’t seem to work for me… I tried the steps in PowerShell 7 and Windows PowerShell 5.1 (Windows 11).

    • Oh – I didn’t see the space between the dots (. .\) to dot source. Never had to do that before – interesting.
      You mentioned it’d be usable to find a logged in user – I tried using * with something like ‘Get-ADComputer’, but I guess it isn’t that simple.

  5. This is great. So did you mention an automated way to log off any sessions discovered? My senior admin gets on to me for not logging off servers I troubleshoot. At the end of my day, I use Citrix Studio to find servers I logged into and log out my sessions. I’d LOVE to do this with a scheduled task.
    There are several hundred servers I could have logged into to and 1 username.

    Is that possible?

Leave a Reply

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