How do I get the current username in Windows PowerShell?
I found it:
[Environment]::UserName
$Env:UserName
There is also:
$Env:UserDomain
$Env:ComputerName
$env:UserName; $env:UserName = "superadmin"; $env:UserName
. This may be acceptable for convenience non-critical uses, but should not be used for security or audit logs. –
Rhone On Windows, you can:
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$env:USERNAME
can be altered by the user, but this will not be fooled by doing that. –
Joel NT AUTHORITY\SYSTEM
, $env:USERNAME
equals to <computername>$
in this case, and $env:USERDOMAIN
is just domain of your computer –
Goetz I thought it would be valuable to summarize and compare the given answers.
If you want to access the environment variable:
(easier/shorter/memorable option)
[Environment]::UserName
-- @ThomasBratt$env:username
-- @Eoinwhoami
-- @galaktor
If you want to access the Windows access token:
(more dependable option)
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
-- @MarkSeemann
If you want the name of the logged in user
(rather than the name of the user running the PowerShell instance).
$(Get-CimInstance Win32_ComputerSystem | select username).username
-- @TwonOfAn on this other forum and updated based on information in comments.
Comparison
@Kevin Panko's comment on @Mark Seemann's answer deals with choosing one of the categories over the other:
[The Windows access token approach] is the most secure answer, because $env:USERNAME can be altered by the user, but this will not be fooled by doing that.
In short, the environment variable option is more succinct, and the Windows access token option is more dependable.
I've had to use @Mark Seemann's Windows access token approach in a PowerShell script that I was running from a C# application with impersonation.
The C# application is run with my user account, and it runs the PowerShell script as a service account. Because of a limitation of the way I'm running the PowerShell script from C#, the PowerShell instance uses my user account's environment variables, even though it is run as the service account user.
In this setup, the environment variable options return my account name, and the Windows access token option returns the service account name (which is what I wanted), and the logged in user option returns my account name.
Testing
Also, if you want to compare the options yourself, here is a script you can use to run a script as another user. You need to use the Get-Credential cmdlet to get a credential object, and then run this script with the script to run as another user as argument 1, and the credential object as argument 2.
Usage:
$cred = Get-Credential UserTo.RunAs
Run-AsUser.ps1 "whoami; pause" $cred
Run-AsUser.ps1 "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name; pause" $cred
Contents of Run-AsUser.ps1 script:
param(
[Parameter(Mandatory=$true)]
[string]$script,
[Parameter(Mandatory=$true)]
[System.Management.Automation.PsCredential]$cred
)
Start-Process -Credential $cred -FilePath 'powershell.exe' -ArgumentList 'noprofile','-Command',"$script"
(you may need a hyphen before noprofile
, like so)
Start-Process -Credential $cred -FilePath 'powershell.exe' -ArgumentList '-noprofile','-Command',"$script"
[Environment]::UserName
is the best option, as it works cross platform. whoami
seems to also work, but depends on the whoami
tool being available on the platform. –
Piker $env:USERNAME
produces SYSTEM
unless I run-as-administrator, while [Environment]::UserName]
yields my username either way. –
Arvizu Get-WmiObject
method no longer works in pwsh. Even tried to import compatibility module and the Microsoft.PowerShell.Management
that has the cmdlet. Any idea what's happening? –
Sneck $(Get-CimInstance Win32_ComputerSystem | select username).username
–
Rifling $env:username
is the easiest way
I'd like to throw in the whoami command, which basically is a nice alias for doing %USERDOMAIN%\%USERNAME%
as proposed in other answers.
Write-Host "current user:"
Write-Host $(whoami)
$env:USERNAME
can be altered by the user, but this will not be fooled by doing that. –
Joel [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
) –
Yogini whoami
is an executable. It can't be removed from PowerShell. It could potentially be removed from Windows, but it's still there as of non-Nano Windows Server 2012. –
Fraze [Environment]::UserName
returns just the user name. E.g. bob
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
returns the user name, prefixed by its domain where appropriate. E.g. SOMEWHERENICE\bob
Now that PowerShell Core (aka v6) has been released, and people may want to write cross-platform scripts, many of the answers here will not work on anything other than Windows.
[Environment]::UserName
appears to be the best way of getting the current username on all platforms supported by PowerShell Core if you don't want to add platform detection and special casing to your code.
I have used $env:username
in the past, but a colleague pointed out it's an environment variable and can be changed by the user and therefore, if you really want to get the current user's username, you shouldn't trust it.
I'd upvote Mark Seemann's answer: [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
But I'm not allowed to. With Mark's answer, if you need just the username, you may have to parse it out since on my system, it returns hostname\username
and on domain joined machines with domain accounts it will return domain\username
.
I would not use whoami.exe
since it's not present on all versions of Windows, and it's a call out to another binary and may give some security teams fits.
[Environment]::UserName
is less typing, independent of $env:username
and cross-platform: See pastebin.com/GsfR6Hrp –
Arvizu Just building on the work of others here:
[String] ${stUserDomain},[String] ${stUserAccount} = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name.split("\")
$username=( ( Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty username ) -split '\\' )[1]
$username
The second username is for display only purposes only if you copy and paste it.
Get-CIMInstance
instead of Get-WMIObject
. Please refer to the article here. –
Depalma I didn't see any Add-Type based examples. Here is one using the GetUserName directly from advapi32.dll.
$sig = @'
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool GetUserName(System.Text.StringBuilder sb, ref Int32 length);
'@
Add-Type -MemberDefinition $sig -Namespace Advapi32 -Name Util
$size = 64
$str = New-Object System.Text.StringBuilder -ArgumentList $size
[Advapi32.util]::GetUserName($str, [ref]$size) |Out-Null
$str.ToString()
UNLEN+1
, and UNLEN
is 256), it disregards any error which might be returned from GetUserName (through it preserves GetLastError, a good point), it does not clean up the string buffer; and probably some others. And as others said, comments are sorely missing, too. –
Alber Sometimes the Username attribute has no data in Win32_ComputerSystem even though there's a user signed in. What works for me is to use quser and parse the output. It's not perfect, but it works. E.g.:
$quserdata = @()
$quserdata = quser
$userid = ($quserdata[1] -split ' ')[1]
$userid
Note: if this is run as the user who is logged in, quser adds '>' symbol to the output. Then you need to get rid of that symbol, but mostly this is needed for code run as system or another account than the one that is logged in.
If you're used to batch, you can call
$user=$(cmd.exe /c echo %username%)
This basically steals the output from what you would get if you had a batch file with just "echo %username%".
$(...)
is superfluous: $a = cmd.exe /c echo %username%
works, b) it's not portable, c) it doesn't actually answer the question of how to do it in powershell, it answers how to do it in dos, and it's better to give a man a fishing pole than give him a fish, e.g. powershell puts environment variables into $env, so %username% = $env:username
. –
Arvizu I find easiest to use: cd $home\Desktop\
will take you to current user desktop
In my case, I needed to retrieve the username to enable the script to change the path, ie. c:\users\%username%. I needed to start the script by changing the path to the users desktop. I was able to do this, with help from above and elsewhere, by using the get-location applet.
You may have another, or even better way to do it, but this worked for me:
$Path = Get-Location
Set-Location $Path\Desktop
In my case, I needed to retrieve the username to enable the script to change the path, ie. c:\users\%username%\
. I needed to start the script by changing the path to the users desktop. I was able to do this, with help from above and elsewhere, by using the get-location applet.
You may have another, or even better way to do it, but this worked for me:
$Path = Get-Location
Set-Location $Path\Desktop
Set-Location Desktop
. (Get-Location
merely returns the current location, which is implicit for a Set-Location
with a relative path.) –
Ollieollis © 2022 - 2024 — McMap. All rights reserved.