Powershell Get Active logged in user in local machine

I am trying to get currently logged in users who has active session.

In the task manager, the list is crystal clear that there are two user sessions and one is active.

I want to query the same via Powershell. I tried few of the available commandsGet-WmiObject Win32_LoggedOnUser | Select Antecedent -Unique which lists lot more users than I can even see [domain joined computer]

I am looking for the query which can give results exactly like Task Manager.enter image description here

8

5 Answers

The issue with Get-WmiObject Win32_LoggedOnUser | Select Antecedent -Unique is that it shows all sessions even those that have been closed since the last time the computer rebooted. The easiest way to poll sessions is unfortunately using the old executable query.exe.

You can convert the output of query.exe to objects using a bit of regex:

$Computer = $env:COMPUTERNAME
$Users = query user /server:$Computer 2>&1
$Users = $Users | ForEach-Object { (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9]{3,})\s+(\d{1,2}\s+\w+)", '$1 none $2' -replace "\s{2,}", "," -replace "none", $null))
} | ConvertFrom-Csv
foreach ($User in $Users)
{ [PSCustomObject]@{ ComputerName = $Computer Username = $User.USERNAME SessionState = $User.STATE.Replace("Disc", "Disconnected") SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "") }
}

Which will give you output like this:

ComputerName Username SessionState SessionType
------------ -------- ------------ -----------
BSMITH-LT bobsm Active console 

Taking it a lot further in to a function:

function Convert-QueryToObjects
{ [CmdletBinding()] [Alias('QueryToObject')] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] [Alias('ComputerName', 'Computer')] [string] $Name = $env:COMPUTERNAME ) Process { Write-Verbose "Running query.exe against $Name." $Users = query user /server:$Name 2>&1 if ($Users -like "*No User exists*") { # Handle no user's found returned from query. # Returned: 'No User exists for *' Write-Error "There were no users found on $Name : $Users" Write-Verbose "There were no users found on $Name." } elseif ($Users -like "*Error*") { # Handle errored returned by query. # Returned: 'Error ...<message>...' Write-Error "There was an error running query against $Name : $Users" Write-Verbose "There was an error running query against $Name." } elseif ($Users -eq $null -and $ErrorActionPreference -eq 'SilentlyContinue') { # Handdle null output called by -ErrorAction. Write-Verbose "Error action has supressed output from query.exe. Results were null." } else { Write-Verbose "Users found on $Name. Converting output from text." # Conversion logic. Handles the fact that the sessionname column may be populated or not. $Users = $Users | ForEach-Object { (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9]{3,})\s+(\d{1,2}\s+\w+)", '$1 none $2' -replace "\s{2,}", "," -replace "none", $null)) } | ConvertFrom-Csv Write-Verbose "Generating output for $($Users.Count) users connected to $Name." # Output objects. foreach ($User in $Users) { Write-Verbose $User if ($VerbosePreference -eq 'Continue') { # Add '| Out-Host' if -Verbose is tripped. [PSCustomObject]@{ ComputerName = $Name Username = $User.USERNAME SessionState = $User.STATE.Replace("Disc", "Disconnected") SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "") } | Out-Host } else { # Standard output. [PSCustomObject]@{ ComputerName = $Name Username = $User.USERNAME SessionState = $User.STATE.Replace("Disc", "Disconnected") SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "") } } } } }
}

and now you can do things like: Get-ADComputer -Filter {Name -like "SERVER*"} | Convert-QueryToObjects | ? {$_.SessionState -eq 'Active'}

2

Here's how I do it. It doesn't work for rdp sessions though.

$out = query session | where {$_ -match 'console'}
$array = $out -split('\s+')
$consoleuser = $array[1]

Or:

$consoleuser = query session | select-string console | foreach { -split $_ } | select -index 1

This can be done with:

get-wmiobject -Class Win32_Computersystem | select Username
2

A little late to the party, but this is how I do it. I get the output from quser, replace tabs with commas and then convert the data from CSV to an object.

$QUserToRichObject = ((Invoke-Expression quser) -replace '\s{2,}', ',' | ConvertFrom-Csv)
If($QUserToRichObject){ $UserSessions = @() ForEach($Record in $QUserToRichObject){ # If the active session, remove the '>' character from Username value If($Record.USERNAME -Like ">*"){$Record.USERNAME = ($Record.USERNAME -Replace ">", "")} $UserSessions += @{ Username = [string]$Record.USERNAME SessionName = [string]$Record.SESSIONNAME ID = [string]$Record.ID State = [string]$Record.STATE Idle = [string]$Record.'IDLE TIME' LogonTime = [string]$Record.'LOGON TIME' } }
}
$UserSessions
<#
Outputs:
Name Value
---- -----
ID 1
SessionName console
Idle none
LogonTime 04/11/2019 14:01
Username SomeUsername
State Active
#>

gwmi win32_process -f 'Name = "explorer.exe"'|% getowner|% user

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like