Use PowerShell to Find Logon Sessions

Summary: Learn how to use Windows PowerShell to discover logon session information for remote computers.

Microsoft Scripting Guy, Ed Wilson, here. This week we will have one guest blogger for the entire week. Sean Kearney has written a series of blog posts about Windows PowerShell and the Legacy. I am not going to be redundant by reposting his biography each and every day.

Here’s Sean…

Here’s a problem I get daily. I need to access a machine because somebody calls complaining about a problem. Most of the time, I can figure out the problem based on the person’s name and their machine name. But sometimes, well…“Things ain’t just the way ya like ‘em.”

I gave up trying to look at the sessions in computer management. In a larger environment, that’s about as slow as a hamster-powered sports car.

So I went back to the basics and found my old friend NET.EXE—see it on a file server? It already has the answer. Problem is, it contains nothing but IP addresses, and I hate navigating that output.  FIND.EXE is good, but it has limitations too!

So I turned to Windows PowerShell to help me out. Combining Windows PowerShell remoting along with some legacy apps gave me a really cool solution.

First, to see what it looks like, I ran the following script in Windows PowerShell.


This showed me all the open sessions on my file server where most of the users home drives were located. (Your environment may be different, so I recommend picking the machine with a file share that most of the users in your environment are likely to attach to.)

Then to quickly find the user, I piped the output as follows.


(NET SESSION) | Select-String mr.trouble


Now to get fancy, I decided to see if I could pass this into the file server via a remote session to allow this to be run from any system.


INVOKE-COMMAND –Session $s –scriptblock { (NET SESSION) | Select-String mr.trouble }


Now at the very least, I could see a much shorter list and resolve those IP addresses to computer names as follows.

nslookup x.x.x.x

But wait.  Don’t I want all of this as a single function?  Don’t I want to make my life easier? What a concept!

I found a small problem in getting the variable to be received by the remote session, so yes…I cheated. I piped after.  I’ll probably look at this later and find the right answer vs. the “cheaters answer.” 

function global:FIND-HSGUSER {

# Get name of File Server to Initialize Remoting
# and the name of the silly user you need to find their computer for   


# Connect Remotely to Server, Run Session, get a list of everybody logged in there

    $S=NEW-PSSESSION –computername $FILESERVER
    $Results=(INVOKE-COMMAND –Session $s –scriptblock { (NET SESSION) }) | Select-string $USERNAME

# Let’s parse through the data and pull out what we need   

Foreach ( $Part in $RESULTS ) {


# Use nslookup to identify the computer, grab the line with the “Name:” field in it

    $Computername=(nslookup $ComputerIP | Where { $_ -like 'Name:'})

    If ($Computername -eq $NULL) { $Computername="Unknown"}
    Else { $Computername=$Computername.substring(9).trim()}

# Show me where the silly fool is hiding

“$User is logged into $Computername with IP address $ComputerIP”



Of course this is a far from a perfect solution. I have found that if the IP address isn’t registered in DNS, it pops out an irritating line that bypasses the console output. But it does show a nice way to make life a little easier on the Administrator with Windows PowerShell and the Legacy.

Take it, use it, abuse it, get creative, and see what YOU can do with existing legacy tools. It’s not “taboo,” it’s power to leverage!

“Legacy rules”…and the Power of Shell too.

Guest blogger week will continue tomorrow when Sean will continue to talk about Windows PowerShell and the Legacy. A special thank you to Sean for writing this week’s blog posts. Hope you enjoy them.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Comments (9)

  1. Joel

    I like that! Another tool to add to our kits!  I LOVE the Power of community here!  Thanks for contributing.  

    If you have a few minutes, could you pop that into the Script Repository?   NICE JOB! 🙂


  2. joel de la torre says:

    If you have enabled 'Audit account logon Events' on your Win2008 server you can query for event: 4768; A Kerberos Ticket Request.  The event has the username and computername where the request originated from.  Just as your request isn't perfect, neither is this.  Its just an alternative if you dont have a share where all your users are connected to.  

    function Get-UserComputerName {



      Searches a specified Domain Controller for the computername of a logged on user.  


      Queries a DC for Event ID 4768 (Kerberos authentication ticket,TGT) request from the servers Security

      event log.

    .PARAMETER UserName

      SamAccount name of the user to search for


      PS> .Get-UserComputerName -UserName "John_Doe" -Server "My_DC"

      Searches for user John_Doe on Domain Controller My_DC


    PS> .Get-UserComputerName -Username "John_Doe"

    Searches for user John_Doe using the logged on server name for the current user

    running the script.


    PS> .Get-UserComputerName

    Searches the current user on the logged on server name


    param([string]$username = $env:username,[string]$server = $env:logonserver)

    $ErrorActionPreference = "silentlycontinue"

    if ($server.StartsWith("\")) {$server = $server.Remove(0,2)}

    $events = Get-WinEvent -ComputerName $server -MaxEvents 5 -FilterHashTable @{logname="security";id=4768;data=$username}

    # Check if error has been raised from EventLog Query.

    if (!$?) {Write-Warning "No successful logon events were found on Server: $server for Username: $username"



    foreach ($event in $events) {

    $myObject = New-Object -TypeName system.Object

    [string]$Computer = $event.message.split("`n") | Select-String "Client Address"

    $addressLine = $computer.replace("Client Address:",'')

    $addressLine = $addressLine.trim()

    if ($addressLine.startswith("::ffff:")) { $address = $addressLine.replace("::ffff:",'') }

    $DNSResult = [system.Net.Dns]::Resolve($address)

    $ComputerName = $DNSResult.HostName

    $timeStamp = $event.timecreated

    $myObject | Add-Member -MemberType noteproperty -Name AuthDC -Value $server

    $myObject | Add-Member -MemberType noteproperty -Name TimeStamp -Value $timeStamp

    $myObject | Add-Member -MemberType noteproperty -Name UserName -Value $username

    $myObject | Add-Member -MemberType noteproperty -Name IPAddress -Value $address

    $myObject | Add-Member -MemberType noteproperty -Name ComputerName -Value $computerName




  3. joel de la torre says:

    I also this on my blog at

  4. James Cook says:

    I’m trying to get this to work for myself on one of my Windows servers. I’m not sure what I’m doing wrong, as I’m new to trying to setup powershell scripts, but it seems like it’s doing something, because it executes, but then it just does nothing. I don’t
    get any output or a request for input. Perhaps I’m using it wrong, somehow?

    Thanks for any help.


  5. Dennis S says:

    @James Cook

    It’s a function with parameters which means u have to add the ‘servername’ and ‘username’ when calling the function. What u probably did was just create the function. However, after creating the function by running Ed Wilson’s script you can call the function
    with the following command:

    FIND-HSGUSER "servernamehere" "usernamehere"

    I’f you enter this command and you are sure servername and username are correct this means the username is not found. To bad the script does not tell you this.

  6. Dennis S says:

    Excuse me i made a mistake, i mean:

    "I’f you enter this command and nothing happens AND you are sure the servername and username are correct this means the username is not found. To bad the script does not tell you this."

  7. Curtis Gray says:

    I struggling with finding a way to use parsing of net session info where the connections are IPv6 – the address is too long to fit in the machine column, so no good way to figure out the full name as it truncates and uses ellipsis which then lead directly
    to the logon name. Ouch.

  8. George says:

    How about a power shell script I can run to locate active sessions on desktops , as I do not have access directly to the domain controllers. I am dealing with extreme lockout issues but asking the associates which machines they logged into isn’t producing
    results. Asking the domain admins for this information is almost liking pulling teeth and looking for a more effective way to isolate which machine they are likely logged into with an old password.

  9. Trevor_T says:

    @George – lockoutstatus – MS utility – google it. Also, psloggedon – another MS utility. By now I figure you have your answer though.

    I just wanted to mention an alternative to nslookup that I love:

    $computer = "corportate_fileserver_01"
    $ip = ""

Skip to main content