[windows] How do I get the current username in Windows PowerShell?

How do I get the current username in Windows PowerShell?

This question is related to windows powershell scripting

The answer is


I found it:

$env:UserName

There is also:

$env:UserDomain
$env:ComputerName

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()

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%".


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 -- @Eoin
  • whoami -- @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-WMIObject -class Win32_ComputerSystem | select username).username -- @TwonOfAn on this other forum

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"

$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.


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


Just building on the work of others here:

[String] ${stUserDomain},[String]  ${stUserAccount} = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name.split("\")

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.


[System.Security.Principal.WindowsIdentity]::GetCurrent().Name

[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


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

$env:username is the easiest way


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'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)

Examples related to windows

"Permission Denied" trying to run Python on Windows 10 A fatal error occurred while creating a TLS client credential. The internal error state is 10013 How to install OpenJDK 11 on Windows? I can't install pyaudio on Windows? How to solve "error: Microsoft Visual C++ 14.0 is required."? git clone: Authentication failed for <URL> How to avoid the "Windows Defender SmartScreen prevented an unrecognized app from starting warning" XCOPY: Overwrite all without prompt in BATCH Laravel 5 show ErrorException file_put_contents failed to open stream: No such file or directory how to open Jupyter notebook in chrome on windows Tensorflow import error: No module named 'tensorflow'

Examples related to powershell

Why powershell does not run Angular commands? How do I install the Nuget provider for PowerShell on a unconnected machine so I can install a nuget package from the PS command line? How to print environment variables to the console in PowerShell? Check if a string is not NULL or EMPTY The term 'ng' is not recognized as the name of a cmdlet VSCode Change Default Terminal 'Connect-MsolService' is not recognized as the name of a cmdlet Powershell Invoke-WebRequest Fails with SSL/TLS Secure Channel Install-Module : The term 'Install-Module' is not recognized as the name of a cmdlet Change directory in PowerShell

Examples related to scripting

What does `set -x` do? Creating an array from a text file in Bash Windows batch - concatenate multiple text files into one Raise error in a Bash script How do I assign a null value to a variable in PowerShell? Difference between ${} and $() in Bash Using a batch to copy from network drive to C: or D: drive Check if a string matches a regex in Bash script How to run a script at a certain time on Linux? How to make an "alias" for a long path?