Table of Contents
This topic can be interpreted as getting all current logged-on users and retrieving one logged-on user in PowerShell. Let’s learn both interpretations.
1. Introduction to the Problem Statement
In network and system administration, it’s often necessary to determine which users are currently logged on to a system. This information can be critical for security, auditing, or managing system resources. PowerShell, with its powerful scripting capabilities, offers several methods to retrieve logged-on user information. We’ll explore these methods, providing examples and expected outputs. The goal is to identify the best approach for different scenarios, considering factors like detail, performance, and environment (local or remote).
2. Using the query Command
One of the quickest ways to get logged-on users is by using the query user
command.
Example:
1 2 3 |
query user |
Output:
1 2 3 4 5 |
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME user1 console 1 Active none 6/17/2021 8:00 AM user2 rdp-tcp#3 2 Active 1+00 6/17/2021 9:30 AM |
Explanation:
- Displays a list of all users logged on, along with session details, idle time, and logon time.
Performance:
- Quick and efficient for local system checks.
3. Using Get-Process
We can inspect user-owned processes to infer logged-on users.
Example:
1 2 3 |
Get-Process | Where-Object {$_.UserName} | Format-Table UserName -Unique |
Output:
1 2 3 4 5 6 |
UserName -------- DOMAIN\user1 DOMAIN\user2 |
Explanation:
We can use the PowerShell command Get-Process | Where-Object {$_.UserName} | Format-Table UserName -Unique
to gather information about the processes running on our computer, specifically focusing on the unique usernames associated with these processes. Let’s break it down:
Get-Process
: This cmdlet allows us to retrieve information about the processes currently running on our computer. It provides a list of all process objects active on the local system.| (Pipe)
: In PowerShell, we use the pipe character to pass the output of one command as input to another. In this instance, it’s used to send the output ofGet-Process
to theWhere-Object
cmdlet.Where-Object {$_.UserName}
:Where-Object
is a cmdlet that filters objects based on specified criteria. Here,{$_.UserName}
is the criterion. The$_
symbol represents each object (process) in the pipeline, and.UserName
accesses itsUserName
property. This filter allows us to select only those processes that have an associated username, essentially excluding system processes and those not linked to a user account.Format-Table UserName -Unique
: Finally, we format the output usingFormat-Table
. This cmdlet arranges our data in a table format, focusing on theUserName
property of the process objects. The-Unique
parameter ensures that each username is listed only once, even if multiple processes are running under the same user account.
By running this command, we effectively get a table of unique usernames for users running processes on our system, providing a clear view of user activity in terms of process execution. It provides an indirect way to identify all active users based on process ownership.
Performance:
- May take longer on systems with many processes but offers comprehensive user activity insights.
4. Using query Command on Remote Server
We can use query user
or qwinsta
command on a remote machine directly. These commands display information about user sessions on a Terminal server or a Remote Desktop Session Host server.
Example:
1 2 3 |
query user /server:DESKTOP-THAT |
1 2 3 4 5 |
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME john console 15 Active 2:26 03/05/2023 6:32 AM mary 16 Disc 2:26 03/05/2023 2:01 PM |
1 2 3 |
query session /server:DESKTOP-THAT |
1 2 3 4 5 6 |
SESSIONNAME USERNAME ID STATE TYPE DEVICE services 0 Disc console John 15 Active Mary 16 Disc |
Explanation:
query user
displays a list of all users logged on, along with session details, idle time, and logon time on remote machine.- Don’t forget to replace the
DESKTOP-THAT
with your remote computer name. Here, the/server:
was used to specify the remote computer/PC name.
Performance:
- Effective for remote administration but dependent on network and remote system performance.
5. Invoke-Command with Win32_LogonSession and Win32_LoggedOnUser for Remote Server
To filter only the remote logged-on users and exclude local users using PowerShell, you’ll need to use a combination of WMI (Windows Management Instrumentation) queries and additional filtering to distinguish between local and remote sessions.
The Win32_LoggedOnUser
class does not directly distinguish between local and remote logins. However, you can use the Win32_LogonSession
class in conjunction with Win32_LoggedOnUser
to determine the nature of the user sessions. Remote sessions typically have a LogonType
value of 10 (RemoteInteractive) in Win32_LogonSession
.
Here’s an example of how we might approach this:
- Query
Win32_LogonSession
to find sessions withLogonType
of 10. - Use the resulting session identifiers to query
Win32_LoggedOnUser
. - Correlate these to get the usernames of remote users.
This can be done with a script block in Invoke-Command
:
1 2 3 4 5 6 7 8 9 10 11 12 |
Invoke-Command -ComputerName "RemoteServer" -ScriptBlock { $remoteSessions = Get-WmiObject -Class Win32_LogonSession | Where-Object { $_.LogonType -eq 10 } $remoteUserSessions = Get-WmiObject -Class Win32_LoggedOnUser foreach ($session in $remoteSessions) { $remoteUserSessions | Where-Object { $_.Antecedent -match "LogonSession='$($session.LogonId)'" } | ForEach-Object { $_ | Select-Object -ExpandProperty Dependent } } } |
This script does the following:
- Retrieves all logon sessions with
LogonType
10 (remote interactive sessions). - Retrieves all logged-on user sessions.
- Filters the logged-on user sessions to include only those that match the remote interactive session IDs.
- Extracts and displays the user information associated with these remote sessions.
Please note that running this script requires appropriate administrative permissions on the remote machine and that PowerShell remoting is properly configured and enabled. Also, the output might need further formatting or processing, depending on your specific requirements.
6. Getting One Currently Logged-on User
In certain scenarios, we might need to identify just one user who is currently logged in, particularly in single-user environments such as personal workstations. PowerShell provides a simple method to fetch the username of the currently active user.
6.1 Using whoami Command
The whoami
command is a quick way to find out the current user’s login name.
Example:
1 2 3 |
whoami |
Output:
1 2 3 |
domain\username |
Explanation:
whoami
simply returns the domain and username of the user currently logged on to the system.- This command is best used in environments where only one user is expected to be active at a time.
Performance:
- The
whoami
command is extremely fast and efficient since it directly queries the current user context.
6.2 Using Get-WmiObject for Detailed Information
For more detailed information, including the domain and the username of the currently logged-on user, Get-WmiObject
can be utilized.
Example:
1 2 3 |
Get-WmiObject -Class Win32_ComputerSystem | Select-Object UserName |
Output:
1 2 3 4 5 |
UserName -------- domain\username |
Explanation:
This command queries the Win32_ComputerSystem
class and retrieves the UserName
property, showing the domain and username.
Get-WmiObject
: This is a PowerShell cmdlet that is used to retrieve Windows Management Instrumentation (WMI) information. WMI is a Windows feature that provides a standardized way to query and set system information and configurations.-Class Win32_ComputerSystem
: This part of the command specifies the WMI class from which to retrieve information.Win32_ComputerSystem
is a WMI class that provides information about a computer system, like its manufacturer, model, and other system-level details.| (Pipe)
: In PowerShell, the pipe character is used to pass the output of one command as input to another command. Here, it’s used to pass the output ofGet-WmiObject
to theSelect-Object
cmdlet.Select-Object UserName, Name
: This cmdlet is used to select specific properties from the objects passed to it. In this case, it’s selecting two properties:UserName
andName
.UserName
refers to the account name of the user currently logged onto the Windows system.Name
refers to the name of the computer system.
So, when we run this command, it will fetch information about the computer system, specifically the username of the currently logged-in user and the name of the computer, and display it. This command is particularly useful in administrative scripts where we need to log or check which user is currently using a specific machine. It is useful for scripts where we need to programmatically access the current user’s details.
Performance:
- Slightly slower than
whoami
but provides additional context, which can be beneficial in scripts.
6.3 Using Invoke-Command for Remote Execution
We can use Invoke-Command
to execute a command on a remote machine. This cmdlet allows us to run scripts or commands on remote computers.
Example:
1 2 3 |
Invoke-Command -ComputerName "RemoteServer" -ScriptBlock { whoami } |
or
1 2 3 |
Invoke-Command -ComputerName "RemoteServer" -ScriptBlock { Get-WmiObject -Class Win32_ComputerSystem | Select-Object UserName } |
Output:
- The first command will output the username of the currently logged-on user on
RemoteServer
. - The second command will provide detailed user information, including the domain and username.
Explanation:
- The
-ComputerName
parameter specifies the remote computer. - The
-ScriptBlock
parameter contains the command to be executed on the remote system. - You must have appropriate permissions and the remote computer must be configured to allow PowerShell remoting.
Performance:
- Performance may vary based on network conditions, remote system load, and configuration.
- It’s an effective method for retrieving user information remotely but requires proper setup for PowerShell remoting.
6.4 Using Remote WMI Queries
Alternatively, we can use WMI directly for querying remote systems without using Invoke-Command
.
Example:
1 2 3 |
Get-WmiObject -Class Win32_ComputerSystem -ComputerName "RemoteServer" | Select-Object UserName |
Output:
1 2 3 4 5 |
UserName -------- domain\username |
Explanation:
- This command remotely queries the
Win32_ComputerSystem
class onRemoteServer
. - It directly retrieves the
UserName
property, showing the currently logged-on user.
Performance:
- Similar to
Invoke-Command
, but it may be more straightforward in environments where WMI is readily accessible and configured for remote queries.
7. Conclusion
Determining logged-on users in PowerShell can be achieved using various methods, each suited to specific needs. The query user
command provides a quick overview, while Get-WmiObject
and Get-Process
offer more detail, especially useful for administrative scripts. For remote systems, Invoke-Command
extends these capabilities across the network. Choosing the right method depends on the specific environment, the level of detail needed, and whether the query is local or remote. Each approach has its own performance considerations and should be selected based on the context of the task.