whoami — Current User Identity#
What it is#
whoami is a built-in Windows command that reports the identity of the currently logged-on user. Beyond the basic DOMAIN\username output, it can display the user’s UPN, SID, all group memberships with SIDs, and the full privilege set — making it the fastest way to diagnose “am I running as the right account?” or “why does this ACL check fail?” in a support session or batch script. The PowerShell equivalents are $env:USERNAME / [System.Security.Principal.WindowsIdentity]::GetCurrent().
Availability#
whoami ships as C:\Windows\System32\whoami.exe on Windows Vista and later (including Server 2008+). It is not present on Windows XP by default.
whoami /?
Output:
WhoAmI has several options. If invoked without switches, it displays
the user name in the "DOMAIN\username" format.
WHOAMI [/UPN | /FQDN | /LOGONID]
WHOAMI { [/USER] [/GROUPS] [/CLAIMS] [/PRIV] } [/FO format] [/NH]
WHOAMI /ALL [/FO format] [/NH]
Syntax#
whoami takes no required arguments; all output is controlled through optional flags.
whoami [/UPN | /FQDN | /LOGONID] [/USER] [/GROUPS] [/PRIV] [/ALL] [/FO TABLE|LIST|CSV] [/NH]
Output: (prints identity information)
Essential options#
| Switch | Meaning |
|---|---|
| (none) | DOMAIN\username |
/USER | User name and SID |
/UPN | User Principal Name (user@domain.com) |
/FQDN | Fully-Qualified Distinguished Name (AD) |
/LOGONID | Logon session ID |
/GROUPS | Group memberships with SIDs and attributes |
/PRIV | Privilege list with state (Enabled / Disabled) |
/ALL | User, groups, claims, and privileges combined |
/FO TABLE|LIST|CSV | Output format |
/NH | Suppress column headers |
Basic output#
Running whoami with no arguments returns DOMAIN\username — the minimum needed to confirm which account is active.
whoami
Output:
myhost\alicedev
On a domain machine the domain replaces the host name:
whoami
Output:
CORP\alicedev
User name and SID#
/USER adds the Security Identifier (SID) alongside the account name — useful when troubleshooting ACL issues where the SID is more authoritative than the name.
whoami /user
Output:
USER INFORMATION
----------------
User Name SID
============== ==============================================
myhost\alicedev S-1-5-21-1234567890-123456789-123456789-1001
UPN and FQDN formats#
/UPN returns the User Principal Name (user@domain) and /FQDN returns the full Active Directory distinguished name. Both require the machine to be domain-joined; they error on standalone workstations.
whoami /upn
Output:
alicedev@corp.example.com
whoami /fqdn
Output:
CN=Alice Dev,OU=Engineering,DC=corp,DC=example,DC=com
Group memberships#
/GROUPS lists every group the user belongs to, including well-known SIDs like BUILTIN\Users and NT AUTHORITY\Authenticated Users, along with the group SID and attribute flags.
whoami /groups
Output:
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
==================================== ================ ============ ====================
Everyone Well-known group S-1-1-0 Mandatory group, ...
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, ...
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, ...
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, ...
...
Privileges#
/PRIV shows all Windows privileges assigned to the token and whether each is currently enabled. A privilege that appears as Disabled can be enabled programmatically; one that is absent cannot be granted without changing the account’s rights.
whoami /priv
Output:
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from dock Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
Full identity dump (/ALL)#
/ALL combines user, groups, claims (if any), and privileges in a single report — the most complete picture of the running token.
whoami /all
Output:
USER INFORMATION
...
GROUP INFORMATION
...
PRIVILEGES INFORMATION
...
CSV output for scripting#
/FO CSV serialises any whoami output into comma-separated form, suitable for parsing with for /f or importing into a spreadsheet.
whoami /groups /fo csv /nh
Output:
"Everyone","Well-known group","S-1-1-0","Mandatory group, Enabled by default, Enabled group"
"BUILTIN\Users","Alias","S-1-5-32-545","Mandatory group, Enabled by default, Enabled group"
...
Common pitfalls#
/UPNfails on non-domain machines — standalone workstations have no UPN; usewhoami(no flag) for the local account name.- Elevation changes the token —
whoami /privrun from an elevated prompt showsSeDebugPrivilegeand others not present in a standard shell; always check from the same elevation level as the process you’re diagnosing. %USERNAME%vswhoami—%USERNAME%is always available without a subprocess but returns only the short username, not the domain. Usewhoamiwhen theDOMAIN\userform or SID is needed.- Group list reflects the logon token — groups added after logon (e.g. after a security group change in AD) won’t appear until the user logs off and back on.
Real-world recipes#
Check whether the current session is elevated (has SeDebugPrivilege)#
whoami /priv | findstr "SeDebugPrivilege"
Output:
SeDebugPrivilege Debug programs Enabled
Log current user to an audit file#
@echo off
for /f "tokens=*" %%u in ('whoami') do set WHO=%%u
echo %DATE% %TIME% — logged in as %WHO% >> C:\Audit\logins.txt
echo Audit entry written.
Output:
Audit entry written.
List only the group names (no SIDs) from CSV output#
for /f "tokens=1 delims=," %g in ('whoami /groups /fo csv /nh') do echo %~g
Output:
Everyone
BUILTIN\Users
NT AUTHORITY\Authenticated Users
...
Confirm domain membership before running a domain-aware script#
@echo off
whoami /upn >NUL 2>&1
if errorlevel 1 (
echo Not domain-joined — skipping AD tasks.
) else (
echo Domain account confirmed. Proceeding.
)
Output:
Not domain-joined — skipping AD tasks.
Claims (/CLAIMS)#
A claim is a Kerberos extension that lets Active Directory attach arbitrary key/value attributes to the user token (e.g. Department=Engineering, Country=US). Dynamic Access Control on file servers reads these claims to make permission decisions without group sprawl. whoami /claims lists everything the local LSA copied off the Kerberos ticket; on a stand-alone workstation or non-claims-aware domain controller the list is empty.
whoami /claims
Output:
USER CLAIMS INFORMATION
-----------------------
User claims
Name: ad://ext/Department
Flags: 0x1
Type: String
Values: Engineering
Name: ad://ext/EmployeeType
Flags: 0x1
Type: String
Values: Full-Time
Kerberos support for Dynamic Access Control on this device has been disabled.
If the bottom line shows disabled, enable claims support via Group Policy under Computer Configuration → Administrative Templates → System → Kerberos → Kerberos client support for claims, compound authentication, and Kerberos armoring.
Logon ID (/LOGONID)#
/LOGONID returns the SID of the current logon session, not the user — this is the LUID-based session SID like S-1-5-5-0-12345. It is the key administrators use to correlate token data to specific sessions in query session, klist sessions, and ETW traces. The value changes every time the user logs in.
whoami /logonid
Output:
S-1-5-5-0-167821
Pair the value with query session to find the corresponding interactive session:
query session
Output:
SESSIONNAME USERNAME ID STATE TYPE DEVICE
services 0 Disc
>console alicedev 1 Active
rdp-tcp 65536 Listen
All output formats — TABLE, LIST, CSV#
/FO accepts TABLE (default, human-readable, fixed columns), LIST (key/value pairs, easier to grep, line-per-attribute), or CSV (quoted, comma-separated, designed for Import-Csv or for /f parsing). /NH strips column headers from TABLE and CSV output so you can pipe directly into other tools without trimming the first row.
whoami /priv /fo list
Output:
Privilege Name: SeShutdownPrivilege
Description: Shut down the system
State: Disabled
Privilege Name: SeChangeNotifyPrivilege
Description: Bypass traverse checking
State: Enabled
whoami /priv /fo csv
Output:
"Privilege Name","Description","State"
"SeShutdownPrivilege","Shut down the system","Disabled"
"SeChangeNotifyPrivilege","Bypass traverse checking","Enabled"
whoami /priv /fo csv /nh
Output:
"SeShutdownPrivilege","Shut down the system","Disabled"
"SeChangeNotifyPrivilege","Bypass traverse checking","Enabled"
LIST is generally the easiest to grep with findstr; CSV is best when piping into PowerShell’s ConvertFrom-Csv for structured handling.
Token integrity level#
Beyond user, groups, and privileges, every Windows token carries a mandatory integrity level (Low/Medium/High/System) that gates the User Account Control sandbox. whoami /groups includes the integrity-level pseudo-SID in its output — looking for it is the fastest way to tell whether the current shell is elevated. The well-known integrity SIDs are:
| SID | Level | When you see it |
|---|---|---|
S-1-16-4096 | Low | AppContainer apps, Edge sandbox |
S-1-16-8192 | Medium | Normal user shells |
S-1-16-8448 | Medium Plus | Rare; UI access |
S-1-16-12288 | High | Elevated (Run as administrator) |
S-1-16-16384 | System | LocalSystem only |
whoami /groups | findstr "Mandatory Level"
Output (non-elevated):
Mandatory Label\Medium Mandatory Level Label S-1-16-8192 Mandatory group, ...
Output (elevated):
Mandatory Label\High Mandatory Level Label S-1-16-12288 Mandatory group, ...
Use this in scripts to refuse to run unless elevated:
@echo off
whoami /groups | findstr /c:"S-1-16-12288" >NUL
if errorlevel 1 (
echo This script must be run as Administrator.
exit /b 1
)
echo Elevated — proceeding.
Output:
Elevated — proceeding.
PowerShell equivalents#
PowerShell exposes the same identity data through [Security.Principal.WindowsIdentity] and friends — without spawning a child process, and with full .NET object output rather than parsed strings. Reach for these whenever you’re already in a PowerShell session.
# Current user (DOMAIN\username)
[Security.Principal.WindowsIdentity]::GetCurrent().Name
# Or the shorter built-in
$env:USERDOMAIN + "\" + $env:USERNAME
# Full identity object
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
$id | Format-List Name, User, AuthenticationType, Token, IsAuthenticated, IsGuest, IsSystem
# SID only
[Security.Principal.WindowsIdentity]::GetCurrent().User.Value
# Groups (NT account names)
[Security.Principal.WindowsIdentity]::GetCurrent().Groups |
ForEach-Object { $_.Translate([Security.Principal.NTAccount]) }
Output (Get-Current):
Name : CORP\alicedev
User : S-1-5-21-1234567890-123456789-123456789-1001
AuthenticationType : Kerberos
Token : 1880
IsAuthenticated : True
IsGuest : False
IsSystem : False
The canonical “am I elevated” check in PowerShell uses the Principal wrapper:
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
$pr = New-Object Security.Principal.WindowsPrincipal($id)
$pr.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
Output:
True
Bundle it into a reusable function:
function Test-IsAdmin {
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
(New-Object Security.Principal.WindowsPrincipal($id)).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator)
}
if (-not (Test-IsAdmin)) { throw 'Run elevated.' }
CIM/WMI for user inventory#
For machine inventory work — listing logged-on users across a fleet — Get-CimInstance is faster than running whoami per host because it returns structured objects directly from the CIM repository.
# Currently logged on console user
Get-CimInstance -ClassName Win32_ComputerSystem |
Select-Object Name, UserName, PartOfDomain, Domain
# All interactive logon sessions (RDP + console)
Get-CimInstance -ClassName Win32_LoggedOnUser |
Select-Object Antecedent -Unique
# Across a fleet via PSRemoting
Invoke-Command -ComputerName web01, web02, web03 -ScriptBlock {
[PSCustomObject]@{
Host = $env:COMPUTERNAME
User = (Get-CimInstance Win32_ComputerSystem).UserName
}
}
Output (Get-CimInstance Win32_ComputerSystem):
Name UserName PartOfDomain Domain
---- -------- ------------ ------
MYHOST CORP\alicedev True corp.example.com
SID and security principal lookups#
whoami shows the current user’s SID, but admins often need to convert between SIDs and account names for ACL or audit work. The classic CLI tool is PsGetSid (Sysinternals); PowerShell does it without a download.
# Name → SID
([Security.Principal.NTAccount]'CORP\alicedev').Translate(
[Security.Principal.SecurityIdentifier]).Value
# SID → Name
([Security.Principal.SecurityIdentifier]'S-1-5-21-1234567890-123456789-123456789-1001').Translate(
[Security.Principal.NTAccount]).Value
Output (Name → SID):
S-1-5-21-1234567890-123456789-123456789-1001
Output (SID → Name):
CORP\alicedev
Look up a remote machine SID (the prefix shared by all local accounts on that host):
$h = 'fileserver01'
([Security.Principal.NTAccount]"$h\Administrator").Translate(
[Security.Principal.SecurityIdentifier]).AccountDomainSid.Value
Comparing whoami with related identity tools#
whoami is the dedicated identity dumper, but several adjacent commands report overlapping data. Pick the right one for the angle you need:
| Command | Best for | Notes |
|---|---|---|
whoami /all | One-shot full token dump | Default for support sessions |
set USERNAME / echo %USERNAME% | Cheap inline checks | No SID/domain info |
klist | List Kerberos tickets | Shows TGT, service tickets, ticket lifetimes |
klist sessions | Logon-session inventory | Pair with whoami /logonid |
gpresult /R | Applied GP + group cache | Includes “User belongs to” |
net user %USERNAME% /domain | AD attributes | Last logon, password change, group list |
query session | Local interactive sessions | Connect ID, idle time |
quser /server:host | Remote interactive sessions | Drop-in for query session |
psgetsid (Sysinternals) | Name ↔ SID lookups for other accounts | Standalone download |
Get-LocalUser (PowerShell) | Local SAM accounts | No domain users |
Common pitfalls (continued)#
whoami /upnerrors with code 1332 — the account has no UPN attribute (userPrincipalName) in AD; check via ADUC orGet-ADUser alicedev -Properties UserPrincipalName.whoami /groupsomits restricted groups — if the token was created byrunas /trustlevel:0x20000(BasicUser), most groups are filtered out; only the user’s primary group and Everyone remain.whoami /fqdnreturns the user DN, not the computer DN — for the computer object, usegpresult /RorGet-ADComputer $env:COMPUTERNAME.- Token caches stale group changes — adding a user to a security group does not flow into the running token; the user must log off and back on, or run
klist purgefollowed by a network operation to refresh the Kerberos ticket. whoami /privonly lists privileges, not rights — user rights like “Log on as a service” are managed by the LSA and shown viasecpol.mscorGet-NetFirewallRule;whoami /privonly enumerates privileges (Se*Privilege) attached to the token.
Real-world recipes (continued)#
Guard a deployment script against the wrong account#
A common bug in scheduled task scripts: the task is registered to run as NT AUTHORITY\SYSTEM when the developer intended CORP\svc_deploy. Guard the script’s entry point so it refuses to do work as the wrong identity.
@echo off
for /f "tokens=*" %%u in ('whoami') do set CURRENT=%%u
if /i not "%CURRENT%"=="corp\svc_deploy" (
echo Refusing to run as %CURRENT% — expected CORP\svc_deploy.
exit /b 2
)
echo Running as %CURRENT% — proceeding with deploy.
Output:
Refusing to run as nt authority\system — expected CORP\svc_deploy.
Snapshot the full token to a timestamped log#
For incident response — capture exactly what the running token looked like at the time something happened.
$stamp = Get-Date -Format yyyyMMdd-HHmmss
whoami /all /fo list > "C:\Audit\token-$env:USERNAME-$stamp.log"
Write-Host "Wrote C:\Audit\token-$env:USERNAME-$stamp.log"
Output:
Wrote C:\Audit\token-alicedev-20260525-093015.log
Diff privilege sets between elevated and non-elevated shells#
rem In a normal shell
whoami /priv /fo csv /nh > %TEMP%\priv-normal.csv
rem Then in an elevated shell
whoami /priv /fo csv /nh > %TEMP%\priv-elevated.csv
fc /n %TEMP%\priv-normal.csv %TEMP%\priv-elevated.csv
Output:
Comparing files priv-normal.csv and priv-elevated.csv
***** priv-normal.csv
3: "SeSecurityPrivilege","Manage auditing and security log","Disabled"
***** priv-elevated.csv
3: "SeSecurityPrivilege","Manage auditing and security log","Disabled"
4: "SeTakeOwnershipPrivilege","Take ownership of files or other objects","Disabled"
5: "SeLoadDriverPrivilege","Load and unload device drivers","Disabled"
*****
The elevated shell shows all the Se*Privilege entries that are filtered out of a standard-user token.
Run only when not logged in as Administrator#
For tools that should never run as the built-in Administrator account (UAC bypasses common safety checks).
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
if ($id.User.Value -eq 'S-1-5-21-*-500') {
Write-Warning 'Refusing to run as built-in Administrator.'
exit 1
}
Forward identity to a remote logging endpoint#
$ident = whoami /all /fo csv /nh | ConvertFrom-Csv -Header User, SID
Invoke-RestMethod -Method POST -Uri https://audit.example.com/login `
-Body (@{ user=$ident.User; sid=$ident.SID; host=$env:COMPUTERNAME } | ConvertTo-Json) `
-ContentType 'application/json'
Related cheat sheets#
- runas — launch a child process under a different identity
- icacls — apply the SIDs
whoamireturns to file/folder ACLs - net-user — query and manage local SAM accounts
- shutdown — requires
SeShutdownPrivilegefromwhoami /priv - powershell-basics —
[Security.Principal.WindowsIdentity]patterns - powershell-builtin-variables —
$env:USERNAME,$env:USERDOMAIN
Sources#
- Following an access token with WinDbg — Chad Duffey (May 2026) — current view of how the kernel resolves the data
whoamisurfaces. - Mastering Windows Access Control: SeDebugPrivilege — Jonathan Johnson — privilege semantics behind
whoami /privEnabledvsDisabled. - The Core of Windows Authorization — Kelvin TC Law — token, SID, and integrity-level reference.
- Abusing Tokens — HackTricks — comprehensive list of
Se*Privilegeentries that may appear inwhoami /priv.