Powershell script to see currently logged in users (domain and machine) + status (active, idle, away)
Solution 1
In search of this same solution, I found what I needed under a different question in stackoverflow: Powershell-log-off-remote-session. The below one line will return a list of logged on users.
query user /server:$SERVER
Solution 2
Since we're in the PowerShell area, it's extra useful if we can return a proper PowerShell object ...
I personally like this method of parsing, for the terseness:
((quser) -replace '^>', '') -replace '\s{2,}', ',' | ConvertFrom-Csv
Note: this doesn't account for disconnected ("disc") users, but works well if you just want to get a quick list of users and don't care about the rest of the information. I just wanted a list and didn't care if they were currently disconnected.
If you do care about the rest of the data it's just a little more complex:
(((quser) -replace '^>', '') -replace '\s{2,}', ',').Trim() | ForEach-Object {
if ($_.Split(',').Count -eq 5) {
Write-Output ($_ -replace '(^[^,]+)', '$1,')
} else {
Write-Output $_
}
} | ConvertFrom-Csv
I take it a step farther and give you a very clean object on my blog.
I ended up making this into a module.
Solution 3
There's no "simple command" to do that. You can write a function, or take your choice of several that are available online in various code repositories. I use this:
function get-loggedonuser ($computername){
#mjolinor 3/17/10
$regexa = '.+Domain="(.+)",Name="(.+)"$'
$regexd = '.+LogonId="(\d+)"$'
$logontype = @{
"0"="Local System"
"2"="Interactive" #(Local logon)
"3"="Network" # (Remote logon)
"4"="Batch" # (Scheduled task)
"5"="Service" # (Service account logon)
"7"="Unlock" #(Screen saver)
"8"="NetworkCleartext" # (Cleartext network logon)
"9"="NewCredentials" #(RunAs using alternate credentials)
"10"="RemoteInteractive" #(RDP\TS\RemoteAssistance)
"11"="CachedInteractive" #(Local w\cached credentials)
}
$logon_sessions = @(gwmi win32_logonsession -ComputerName $computername)
$logon_users = @(gwmi win32_loggedonuser -ComputerName $computername)
$session_user = @{}
$logon_users |% {
$_.antecedent -match $regexa > $nul
$username = $matches[1] + "\" + $matches[2]
$_.dependent -match $regexd > $nul
$session = $matches[1]
$session_user[$session] += $username
}
$logon_sessions |%{
$starttime = [management.managementdatetimeconverter]::todatetime($_.starttime)
$loggedonuser = New-Object -TypeName psobject
$loggedonuser | Add-Member -MemberType NoteProperty -Name "Session" -Value $_.logonid
$loggedonuser | Add-Member -MemberType NoteProperty -Name "User" -Value $session_user[$_.logonid]
$loggedonuser | Add-Member -MemberType NoteProperty -Name "Type" -Value $logontype[$_.logontype.tostring()]
$loggedonuser | Add-Member -MemberType NoteProperty -Name "Auth" -Value $_.authenticationpackage
$loggedonuser | Add-Member -MemberType NoteProperty -Name "StartTime" -Value $starttime
$loggedonuser
}
}
Solution 4
Maybe you can do something with
get-process -includeusername
Solution 5
If you want to find interactively logged on users, I found a great tip here :https://p0w3rsh3ll.wordpress.com/2012/02/03/get-logged-on-users/ (Win32_ComputerSystem did not help me)
$explorerprocesses = @(Get-WmiObject -Query "Select * FROM Win32_Process WHERE Name='explorer.exe'" -ErrorAction SilentlyContinue)
If ($explorerprocesses.Count -eq 0)
{
"No explorer process found / Nobody interactively logged on"
}
Else
{
ForEach ($i in $explorerprocesses)
{
$Username = $i.GetOwner().User
$Domain = $i.GetOwner().Domain
Write-Host "$Domain\$Username logged on since: $($i.ConvertToDateTime($i.CreationDate))"
}
}
RayofCommand
new to programming and scripting. 2013/06/21 I do enjoy: Powershell ServiceNow
Updated on July 09, 2022Comments
-
RayofCommand almost 2 years
I am searching for a simple command to see logged on users on server. I know this one :
Get-WmiObject -Class win32_computersystem
but this will not provide me the info I need. It returns : domain Manufactureer Model Name (Machine name) PrimaryOwnerName TotalPhysicalMemory
I run Powershell 3.0 on a Windows 2012 server.
Also
Get-WmiObject Win32_LoggedOnUser -ComputerName $Computer | Select Antecedent -Unique
gives me not the exact answers I need. I would love to see as well the idle time, or if they are active or away.
-
RayofCommand about 10 yearsI added the missing } in the end and changed the computername variable and set it to my hostname. But still i can't make this run. somehow it tries to use my machinename as cmdlet. If i explicitly Set-Variable -Name computername -Value “mymachinename” i get and RPC server is unavailable. I am still newbie, what do i miss?
-
mjolinor about 10 yearsSorry about the missing bracket (copy/paste fail). Fixed. Not sure why it's not working. After the function is loaded, you should be able to just run" get-loggedonuser <computername>. For the local machine, you can run: get-loggedonuser localhost
-
RayofCommand about 10 yearsstill wasn't able to make it work. even if i replace the $computername directly using my machinename or localhost i didnt get any result. Is there a way to see the info of how long the user is logged in?
-
mjolinor about 10 yearsIf you look at that function, you'll see it also returns the starttime of the session, so you can calculate from that. But that doesn't help if it won't work on your machine, and I can't reproduce the error your getting to debug it.
-
RayofCommand about 10 yearshmm i think you missed 40% of your own script. i just took the one from you posted on technet page. this as well has the session start time
-
mjolinor about 10 yearsYou're right. That's what I get for copying code out of my profile. Sorry about that. I updated the answer. Does that code to what you need?
-
RayofCommand about 10 yearsyep. thanks. Unfortunately I am not now able to select only the RemoteInteractive Users, can you help me out :)?
-
mjolinor about 10 yearsSimple Where-Object filter. Get-LoggedOnuser <machine> | Where {$_.LogonType -eq 'RemoteInteractive'}
-
RayofCommand about 10 yearsthanks. But we need to use Type instead of LogonType. now it works as expected
-
Aaron over 8 yearsIs there a way to just pull the usernames and throw them on one line? I don't care much to know the session and start time, etc for certain things.
-
Michael Trouw over 8 yearsFun fact: linux equivalent: the 'w' command. of course, with Winblows, nothing has to be simple if it can be complicated.
-
mjolinor over 8 yearsWell, that's 30 seconds of my life I'll never get back.
-
shivshankar about 8 yearsThis is a much better solution than the accepted answer. The accepted answer gives you all the users that are running services and and applications, not active RDP sessions or console sessions.
-
Code Jockey about 8 yearsI would go ahead and agree that it is a better answer to the question, in that the OP wanted a
simple command
, and so I've upvoted it, but I was looking for more functionality and Google sent me here, so for my purposes, mjolinor's answer is more useful, so I've upvoted that one... hmmmm -
Kumar Sambhav Pandey almost 8 years@mjolinor Hi Your script is working fine but on running the same it shows only my name i.e. {Session : 39648199 Type : Local System Auth : StartTime : 1/1/1601 5:30:00 AM}. I want to see how many users are currently logged in and are active (say in last 30 minutes), how can I do that ? Could you please help me with that ?
-
Jaans almost 7 yearsLike the lateral thinking. I know it isn't the "correct" answer, but it does present a potential workaround solution.
Get-Process -IncludeUserName | Select-Object -Unique -Property UserName
-
SamAndrew81 almost 7 yearsBrilliant and exactly what I was looking for!
-
as9876 over 6 yearsUnless the user is using a custom shell other than explorer.exe docs.microsoft.com/en-us/windows-hardware/customize/enterprise/…
-
user2305193 over 6 yearsdoesn't give you the machine name?
-
KawaGreen about 6 yearsThis needs more upvotes. Spent too long trying to get it to format the way I wanted.
-
Rakha almost 6 yearsIndeed, this is BRILLIANT!
-
Carl Walsh over 5 yearsThis listed 18 sessions, including some users as Interactive that aren't even logged in. Also, the sessions were in the millions, when I was expecting single-digits...
-
not2qubit about 4 yearsThis give me:
query: The term 'query' is not recognized...
. So what am I missing here? -
not2qubit about 4 years
quser
is not recognized under PS. What's missing? -
VertigoRay almost 4 yearsPulling the username off a process, other than your own, requires admin rights.
-
VertigoRay almost 4 years@not2qubit, are you running on Windows? If so, check your path.
quser
is an executable:C:\WINDOWS\system32\quser.exe
. You can also tryquery user
, it returns the exact same output.query
is also an executable:C:\WINDOWS\system32\query.exe
-
not2qubit almost 4 years@VertigoRay I don't have those *.exe files on my system... (Win8.1).
-
VertigoRay almost 4 years@not2qubit Home Edition? If so, it's likely the issue or your installation is corrupt or incomplete. For help on that: answers.microsoft.com/en-us/windows/forum/all/…
-
not2qubit almost 4 years@VertigoRay No, that's not right. I don't have this command on Win10 (Home) either. So I think it might be a server specific command.
-
VertigoRay almost 4 years@not2qubit Like I said, it's not available on the Home SKUs. I have it available on Pro and Enterprise SKUs of Win10, and my brother confirmed that
query user
andquser
are not available on Win10 1909 Home. Since you cannot RDP into a Home SKU, it's a bit irrelevant to run this command locally. -
not2qubit almost 4 years@VertigoRay Thanks, but that was not clear at all. Also, there are several other and better ways than RDP, so definitely not irrelevant.
-
VertigoRay almost 4 years@not2qubit Apologies for not being clear. I'm curious what your other/better ways are. Tools like VNC/Teamviewer/LogMeIn connect to the console session, and
quser
isn't the right tool for seeing if someone is connected via those services. -
VertigoRay almost 4 years@not2qubit If you were not running Windows Home edition, you might be running PowerShell 32-bit on a 64-bit OS and unable to find
quser
. In which case, you would need to useSysNative
to get to the realSystem32
folder:C:\Windows\SysNative\quser.exe
-
Hyon almost 4 yearsWhat version of Windows and Powershell are you running? Can you run "get-command query" and verify that it is located at c:\WINDOWS\system32\query.exe.
-
stackprotector about 3 yearsThis method does not list users, that are logged on via SSH (built-in OpenSSH).
-
dragonspeed over 2 yearsOn my system - no idle time is designated as "none" and your script breaks. PS C:\WINDOWS\system32> query user USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME >some.user console 1 Active none 8/17/2021 5:32 AM Sorry - comment formatting won't show it as correctly formatted :(
-
Leon Bouquiet over 2 yearsOk, off the top of my head, you could try changing
if($parts[5] -ne '.')
intoif(@('.', 'none') -notcontains $parts[5])
and see if that works? -
dragonspeed over 2 yearsChanged it to: $(if($parts[5] -ne '.' -and $parts[5] -ne 'none') - All good - works for remote (although there is no "current" user in remote checking
-
Tilo over 2 yearssame Q as @user2305193 ; any way to see the client-name of the user who RDP (visible via Task Manager Users)
-
Tilo over 2 yearsfor client-name see also other questions stackoverflow.com/q/48456277/1747983 ; seems PSTerminalServices has this option (first import module)
-
T-Heron over 2 yearsNote that this requires Admin rights in order to run
-
AnrDaemon about 2 yearsWhich would not work, if user's shell is NOT
explorer.exe
(sorry for stating the obvious).