Need to find the logged on user on windows 10 machine

Hi Team,
i am using the below command to retreive the logged on user on win10 machine

$userInfo = Get-WmiObject -Class Win32_ComputerSystem
$($userInfo.UserName)

The problem with this command is that it only retreives the console logon user and not the rdp user.

is there any command which will give us both the rdp as well as console user?

Hello,

This is a very common topic that I’m sure has thousands of results on your preferred search engine. Have you attempted to search for it? My initial search shows dozens of possible solutions.

https://www.google.com/search?q=powershell+command+to+show+currently+logged+in+users&sca_esv=7b4f5aad248322ac&sca_upv=1&rlz=1C1GCEA_enUS994US994&sxsrf=ACQVn08ZtRaO7T_Qaur1QeSvSzNK3woJuA%3A1711736247816&ei=twUHZpS3MfTnkPIP9pSSwAw&ved=0ahUKEwjU7v-3ipqFAxX0M0QIHXaKBMgQ4dUDCBA&uact=5&oq=powershell+command+to+show+currently+logged+in+users&gs_lp=Egxnd3Mtd2l6LXNlcnAiNHBvd2Vyc2hlbGwgY29tbWFuZCB0byBzaG93IGN1cnJlbnRseSBsb2dnZWQgaW4gdXNlcnMyBhAAGBYYHjIGEAAYFhgeMgsQABiABBiKBRiGA0jV5QJQhr4CWObkAnADeAGQAQGYAZgBoAGbEKoBBDI1LjG4AQPIAQD4AQGYAhygAsYPwgIKEAAYRxjWBBiwA8ICBBAjGCfCAgUQABiABMICBxAAGIAEGA2YAwCIBgGQBgiSBwIyOKAHssEB&sclient=gws-wiz-serp

Check those out and I’m sure you’ll find something that does what you need. :slight_smile:

this does seem to be a common topic for Powershellers. I wrote something a long time ago that used CIM and the same Win32_ComputerSystem class to pull the logged on user. Something like this inside a try/catch:

 [ValidateNotNullOrEmpty()]$UserId = Get-CimInstance -Class "Win32_Computersystem" -ErrorAction Stop | Select-Object -ExpandProperty UserName  

Coincidentally just this past Friday I was helping someone make a Lock-Screen function and ran in to what you did; if the user is connected via RDP that Win32_ComputerSystem class won’t tell us their username. I went back to the googs and scoured the internet trying to find a better way and my end result was that there isn’t really a native Powershell way that’s reliable. So, I used my wrapper function for quser so I could key off of object properties.

Function Invoke-Quser {
    <#
    .SYNOPSIS
    A wrapper for Quser.exe to return Powershell objects
    .DESCRIPTION
    Executes Quser locally or against a remote computer and returns the results as Powershell objects
    .PARAMETER ComputerName
    Remote  computername for use with "/SERVER" parameter within Quser.exe
    .PARAMETER UserorSession
    If you know the username, sessionID number, or Session type you can pass that to this parameter.
    .EXAMPLE
    PS C:\> Invoke-Quser

    Username    : John123
    SessionID   : 1
    SessionName : Console
    State       : Active
    LogonTime   : 2/17/2022 8:27:00 AM
    .Notes
    Version:        1.3
    Author:         C. Bodett
    Creation Date:  5/11/2022
    Purpose/Change: Changed the split method on the user info row to be more like github.com/UNT-CAS/QuserObject implementation. Borrowed a lot of their methodology from that module and used it here.
    #>
    [cmdletbinding()]
    Param (
        [Parameter(Mandatory = $false, Position = 0)]
        [String]$ComputerName = "Localhost",
        [Parameter(Mandatory = $false)]
        [String]$UserorSession
    )

    if ($ComputerName -eq "Localhost") {
        $Qcmd = '{0} {1}'
    } else {
        $Qcmd = '{0} {1} /SERVER:{2}'
    }

    $Quser = $Qcmd -f 'quser.exe', $UserorSession, $ComputerName

    try {
        $Results = (Invoke-Expression $Quser) 2>&1
    } catch {
        $Results = $Error[0].Exception.Message
    }

    if ($LASTEXITCODE -eq 0) {
        $QUserOutput = Foreach ($Result in ($Results | Select-Object -Skip 1)) {
                        $ParsedLine = $Result -split '\s{2,}'
                        [System.Collections.Generic.List[String]]$SessionInfo = $ParsedLine | Select-Object -Skip 1
                        if ($SessionInfo.Count -eq 4) {
                            # session name is blank. adding a blank entry to the array
                            $SessionInfo.Insert(0,'')
                        }
                        $IdleTime = if ($SessionInfo[3] -eq "none" -or $SessionInfo[3] -eq '.') {
                                "none"
                            } else {
                                If ($SessionInfo[3] -as [Int]) {
                                    $SessionInfo[3] = "0:$($SessionInfo[3])"
                                }
                                [Timespan]$QuserIdle = $SessionInfo[3].Replace('+','.')
                                $QuserIdle
                            }
                        $UserInfo = [PSCustomObject]@{
                            ComputerName = $ComputerName
                            Username = $ParsedLine[0].TrimStart('>').Trim()
                            SessionID = [Int]$SessionInfo[1]
                            SessionName = $SessionInfo[0]
                            State = $SessionInfo[2]
                            IdleTime = $IdleTime
                            LogonTime = Get-Date $SessionInfo[4]
                        }
                        $UserInfo
                    }
        return $QUserOutput
    } else {
        Write-Warning $Results.Exception.message
    }
}  

Try this out. Bare in mind that if there are multiple users signed in (even if disconnected) Invoke-Quser will return multiple objects, so code appropriately for that.

not PS but this seems to work for both console and RDP:

query user /server:$ServerName

Also keep in mind you can pretty easily run two commands instead of 1 if you need two different pieces of data, and just create a PowerShell function that makes it all into a pretty output.

I do see quser mentioned a ton just from a few google searches, so greyout’s probably works as well, but the one liner above is super easy.

A bit ironic I’ve never needed to really do this in my workplace heh.