Identify what servers a user is logged on to with powershell

Identify what servers a user is logged on to with powershell

I am guilty to disconnect from a server and forget all about it and perhaps, months later, I find myself logged on that server. I built a quick script that helps me with this every now and then. Or perhaps you’re onto somebody else 🙂 Let’s see how to identify what servers a user is logged on to with powershell!

First things first, you will need a list of servers (this will work on all clients as long as you have rights to query all of the machines).
I prefer to grab the list from Active Directory (you will need AD-RSAT tools with Powershell unless you run this on a Domain Controller) with the following command:

#The command will also exclude any disabled machine to avoid wasting time to try to reach them.
$serverList=(Get-ADComputer -Filter ('(OperatingSystem -Like "*SERVER*") -AND (Enabled -Eq "True")') | select-object Name).Name

If you have already a simple list of hostnames stored in a text file, you can import it with:

$serverList = Get-Content "C:\Users\ItdropletsUser\desktop\servers.txt"

Let’s see the whole script, it’s commented so that you can understand, but I’ll go through it:

#The username to check against each server
$Username = "user.name"

#Output file
	$csvOutput = 'C:\whereisloggedon.csv'
		#Deletes the output file if it exists
			If (Test-Path $csvOutput){
				Remove-Item $csvOutput
			}
		#Add the first line to the CSV file
		Add-Content -Path $csvOutput -Value "Hostname,SessionID"

#Get all Servers' names in the Domain that are not enabled.
$serverList=(Get-ADComputer -Filter ('(OperatingSystem -Like "*SERVER*") -AND (Enabled -Eq "True")') | select-object Name).Name

#Start a foreach cycle which will go through each Server in the ServerList
foreach ($Server in $serverList)
	{
		#Ping the Server
		$ping = Test-Connection $Server -Count 1 -EA Silentlycontinue

		#If Ping is successfull then keep going
		if($ping)
		{
			#Get server session ID if $username is logged on - cmd /c is needed for the 2>NUL to avoid quser to write "No User exists for *" when nobody is logged on a server.
			$sessionID = ((cmd /c quser /server:$server "2>NUL"| ? { $_ -match $username }) -split ' +')[2]
			
			#If sessionsID exists, write it to console and to the output file but exclude any live RDP connection or console (ie: rdp-tcp#1)
				If ($sessionID -AND $sessionID -NotLike "*rdp*" -AND $sessionID -ne "console")
				{
					#Write to console
					Write-Host "$($Username) is logged on $($Server) with ID: $($sessionID)"
					#Write into $csvOutput
						Add-Content -Path $csvOutput -Value "$($Server),$($sessionID)"
				}
		}
	}

So what’s happening is very simple:

  1. First I stated the username (just the username and not the domain etc).
  2. The csvOutput is the file that will be stored in C:\ which will contain a list of Hostames and Session IDs. In the script I also initialised it so that the first line will have Hostname,Session ID.
  3. I then grabbed the list of servers that are not disabled from Active Directory.
  4. In the foreach cycle, I went through each server in the Server List. For each server the script will:
    • Try to ping it (with just one request to make it faster).
    • Grab the session ID when the user matches. This is the most important line of the script. Also note that I used cmd /c so that I could use “2>NUL”. This is a nice workaround to avoid the script to output No User exists for *. This output is displayed every time quser hits a server with no users logged on to it.
    • Check if the Session ID exists, it makes sure it doesn’t contain “rdp” and that does not contain “console”. In my opinion we should avoid to grab a list of active sessions, especially if you want to use the csv file at a later stage to kill these sessions. Perhaps you’re logged off and you’re going to kill an active session from another user, losing all of his/her work!
    • If the Session ID respected the above criteria, then write to console something like User.Name is logged on SERVER01 with ID:5 and then it’ll also write SERVER01,5 in the CSV file.

That’s it! This is how you identify what servers a user is logged on to with powershell.

Note: Somebody might suggest a different approach which is grabbing all explorer.exe on the server and then check its owner in another cycle. I do not like this approach as you might be in an environment with servers running without a GUI!

IT Droplets

IT Droplets