Oct 17, 2016

How to find a logged-in user remotely using PowerShell Script in Windows

A common task any Windows admin might have is finding out, locally or remotely, which user account is logged onto a particular computer. Many tools exist for this purpose, and one of them, of course, is PowerShell.





A Windows admin might need this information to create reports, to track down malware infection or to see who’s in the office. Since this is a repeatable task, it’s a good idea to build a script that you can reuse over and over again, rather than having to figure out how to do it every time.

In this article, I’m going to go over how to build a PowerShell script to find a logged-on user on your local Windows machine, as well as on many different remote Windows machines at once. By the end, you should have a good understanding of what it takes to query the logged-on user of a Windows computer. You will also understand how to build a PowerShell script to execute the command on multiple computers at the same time.

With PowerShell, getting the account information for a logged-on user of a Windows machine is easy, since the username is readily available using the Win32_ComputerSystem WMI instance. This can be retrieved via PowerShell by using either the Get-CimInstance or Get-WmiObject cmdlet. I prefer to use the older Get-WmiObject cmdlet because I’m still working on older machines.
Get-WmiObject –ComputerName CLIENT1 –Class Win32_ComputerSystem | Select-Object UserName 

Output 
Output

If you prefer to use CIM, you can also use Get-CimInstance to return the same result.

Get-CimInstance –ComputerName CLIENT1 –ClassName Win32_ComputerSystem | Select-Object UserName
I suppose you could say I did just show you how to discover a logged-on user remotely. However, we need to make this reusable, more user-friendly and easy to perform on multiple computers. Let’s take it a step further and build a PowerShell function from this.

First, let’s build our template function. It looks like this:

function Get-LoggedOnUser
 {
     [CmdletBinding()]
     param
     (
         [Parameter()]
         [ValidateScript({ Test-Connection -ComputerName $_ -Quiet -Count 1 })]
         [ValidateNotNullOrEmpty()]
         [string[]]$ComputerName = $env:COMPUTERNAME
     )
 }
Here, we have an advanced function with a single parameter: ComputerName. We also want to incorporate some parameter validations to ensure that the computer responds to a ping request before we query it. Also, notice the parameter type: [string[]]. Notice how there is an extra set of brackets in there? This makes ComputerName a string collection, rather than just a simple string. This is going to allow us to specify multiple computer names, separated by commas. We’ll see how this comes into play a bit later.

Once we have the function template down, we’ll need to add some functionality. To do that, let’s add a foreach loop, in case $ComputerName has multiple computer names, and then create a custom object for each computer, querying each for the logged-on user.

function Get-LoggedOnUser
 {
     [CmdletBinding()]
     param
     (
         [Parameter()]
         [ValidateScript({ Test-Connection -ComputerName $_ -Quiet -Count 1 })]
         [ValidateNotNullOrEmpty()]
         [string[]]$ComputerName = $env:COMPUTERNAME
     )
     foreach ($comp in $ComputerName)
     {
         $output = @{ 'ComputerName' = $comp }
         $output.UserName = (Get-WmiObject -Class win32_computersystem -ComputerName $comp).UserName
         [PSCustomObject]$output
     }
 }
Here, notice that instead of outputting only the username, we are building a custom object that outputs the computer name as well, so that when multiple computer names are used, I can tell which username coincides with which computer.

Now, let’s run this and see what the output looks like when we don’t specify a computer name.


Without specified computer name 
Without specified computer name

My local computer name is WINFUSIONVM, and I am logged in through a local account called Adam. Now, let’s see what it looks like when we query a remote computer. 

Queried a remote computer 





Queried a remote computer

In the instance above, notice that the account exists within a domain. We know this because the username starts with MYLAB, rather than MEMBERSRV1.

Finally, let’s pass a couple different computer names through this function.

Different computer names
Different computer names

You can see that CLIENT2’s UserName is null. This is because no account is currently logged on the computer.

If you’d like a fully featured function with error control, feel free to download this function from my Github repo.

Post a Comment

 
TECH SUPPORT © 2012-2016