如何在Windows PowerShell中获取当前的用户名?


Answers:


397

我找到了:

$env:UserName

还有:

$env:UserDomain
$env:ComputerName

10
一种快速而肮脏的选择是$env:username从相应的环境变量中检索用户名。
guillermooo,2010年

7
我认为$ env:username和[Environment] :: UserName都指向同一件事。
Cephas

16
感谢您回来回答您自己的问题。当有人自己弄清楚答案并简单地回答:“没关系,明白了!”时,没有什么比这更令人沮丧了。
马特·迪特罗里奥

6
@MattDiTrolio当然令人沮丧,但您认为没有什么比这更令人沮丧了!
赛马会

5
@CodeJockey没事。从未有过的历史。:)
Matt DiTrolio 2015年

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

16
这是最安全的答案,因为$env:USERNAME用户可以更改它,但是这样做不会被愚弄。
凯文·潘科2014年

6
@KevinPanko是的,但是在您不能信任用户的时候,还有其他一些更哲学的问题需要提出。;-)
jpaugh

4
此方法包括域名和用户名。如果您有多个域,这绝对是有利的。
瑞安·盖茨

可以正常工作。经过测试的网址保留。
Marek Bar

此外,这看起来也可以在PowerShell 6中工作,这意味着它与跨平台(.Net Standard)兼容。认为值得一提,因为我在看到名称空间时提出了质疑。
deadlydog

120

我认为总结和比较给出的答案将很有价值。

如果要访问环境变量

(更容易/更简短/值得纪念的选项)

  • [Environment]::UserName -@ThomasBratt
  • $env:username -@伊恩
  • whoami -@galaktor

如果要访问Windows访问令牌

(更可靠的选择)

  • [System.Security.Principal.WindowsIdentity]::GetCurrent().Name -@MarkSeemann

如果要登录用户的名称

(而不是运行PowerShell实例的用户的名称)

  • $(Get-WMIObject -class Win32_ComputerSystem | select username).username-在另一个论坛上的 @TwonOfAn

比较方式

@Kevin Panko对@Mark Seemann的回答的评论涉及选择一个类别而不是另一个类别:

[Windows访问令牌方法]是最安全的答案,因为用户可以更改$ env:USERNAME,但是这样做不会被愚弄。

简而言之,环境变量选项更加简洁,Windows访问令牌选项更加可靠。

我必须在具有模拟功能的C#应用​​程序中运行的PowerShell脚本中使用@Mark Seemann的Windows访问令牌方法。

C#应用程序使用我的用户帐户运行,并且将PowerShell脚本作为服务帐户运行。由于我从C#运行PowerShell脚本的方式受到限制,因此PowerShell实例使用我的用户帐户的环境变量,即使它以服务帐户用户身份运行。

在此设置中,环境变量选项返回我的帐户名,Windows访问令牌选项返回服务帐户名(这是我想要的名称),而登录用户选项返回我的帐户名。


测验

另外,如果您想自己比较选项,则可以使用以下脚本以另一个用户身份运行脚本。您需要使用Get-Credential cmdlet获取凭据对象,然后运行该脚本,并以另一个用户作为参数1和凭据对象2作为参数运行该脚本。

用法:

$cred = Get-Credential UserTo.RunAs
Run-AsUser.ps1 "whoami; pause" $cred
Run-AsUser.ps1 "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name; pause" $cred

Run-AsUser.ps1脚本的内容:

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"

对于Mac OS X和Linux上的PowerShell 6,[Environment]::UserName是最佳选择,因为它可以跨平台工作。whoami似乎也可以,但是取决于whoami平台上可用的工具。
Florian Feldhaus

对于Windows上的Powershell 6,除非我以管理员身份运行,否则$env:USERNAME会生成SYSTEM,而会[Environment]::UserName]以两种方式生成用户名。
kfsone

1
似乎该Get-WmiObject方法在pwsh中不再起作用。甚至尝试导入兼容性模块Microsoft.PowerShell.Management,并且该命令具有cmdlet。知道发生了什么吗?
not2qubit

正确。有人烦扰到GET-CimInstance好半天回性能的原因...和CIM 被使用过WMI在V6的交叉兼容性原因。如果看到带有GWMI的命令,请检查是否可以执行GCIM。
Hicsy

105

$env:username 是最简单的方法


您可以通过这种方式进行分配,并建立目录,而不要建立目录。
Droogans 2012年

51

我想输入whoami命令,该命令基本上是%USERDOMAIN%\%USERNAME%其他答案中所建议的一个很好的别名。

Write-Host "current user:"
Write-Host $(whoami)

它在PS版本2上对我有效。您是说它已在PS3中删除了吗?C:\> powershell Windows PowerShell版权所有(C)2009 Microsoft Corporation。版权所有。PS C:\> whoami mydomain \ myusername
galaktor 2013年

2
$env:USERNAME可以由用户更改,但是这样做不会被愚弄。
凯文·潘科2014年

3
whoami赢得互动使用。足够短,我可以记住如何在不咨询SO的情况下键入它:-)
Iain Samuel McLean Elder 2014年

在Nano Server中不是一回事。不要在脚本中使用它,请执行正确的操作([System.Security.Principal.WindowsIdentity]::GetCurrent().Name
另一个用户

whoami是可执行文件。无法将其从PowerShell中删除。它可能从Windows中删除,但它仍然存在非纳米的Windows Server 2012的
jpmc26

37

[Environment]::UserName仅返回用户名。例如,bob [System.Security.Principal.WindowsIdentity]::GetCurrent().Name返回用户名,并在适当时添加其域前缀。例如SOMEWHERENICE \ bob


12

我用过了 $env:username过,但是一位同事指出这是一个环境变量,用户可以更改它,因此,如果您确实想获取当前用户的用户名,则不应信任它。

我赞成Mark Seemann的回答:[System.Security.Principal.WindowsIdentity] :: GetCurrent()。Name

但是我不被允许。用Mark的答案,如果只需要用户名,则可能必须解析它,因为在我的系统上,它会返回,hostname\username而在具有域帐户的加入域的计算机上,它将返回domain\username

我不会使用whoami.exe它,因为它并非在所有版本的Windows上都存在,并且它是对另一个二进制文件的调用,可能会使某些安全团队感到满意。


1
由于OP确实询问了有关Windows-Powershell的问题,因此这是有效的,但[Environment]::UserName键入较少,独立$env:username且跨平台的:请参阅pastebin.com/GsfR6Hrp
kfsone

12

既然已经发布了PowerShell Core(aka v6),并且人们可能想编写跨平台脚本,那么这里的许多答案都不适用于Windows以外的任何其他软件。

[Environment]::UserName 如果您不想在代码中添加平台检测和特殊大小写,则似乎是在PowerShell Core支持的所有平台上获取当前用户名的最佳方法。


10

只是在这里基于其他人的工作:

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

1
$username=( ( Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty username ) -split '\\' )[1]

$username

第二个 用户名是仅用于显示的目的只有当你复制和粘贴。


$ fullname = Get-WMIObject -class Win32_ComputerSystem | 选择对象-ExpandProperty用户名$ username = $ fullname.Replace(“ DOMAIN \”,“”)$ username
clayton.nichols

-1

我没有看到任何基于Add-Type的示例。这是直接从advapi32.dll使用GetUserName的一种。

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

1
请解释此代码的作用以及为什么它比较短的方法之一更有用。
本杰明·哈伯德

@BenjaminHubbard这个问题并没有要求最短的方法,而是询问如何用powershell完成这一壮举。通过在dll中调用该函数并使用Add-Type方法访问.NET,此技巧与其他示例不同。
Knuckle-Dragger 2015年

1
虽然这是一个新颖的代码块,但如果我知道它在做什么,那将很棒。可以用注释注释它吗?谢谢!
jpaugh

1
我几乎想投票赞成,因为我看到了建议的好处。但是代码存在一些缺陷:它引入了一个新的命名空间,它使用了一个魔术常数(64),该常数不是医生指定的值(应为UNLEN+1UNLEN为256),它忽略了可能从GetUserName返回的任何错误(通过它保留了GetLastError,这是一个好主意),它不会清理字符串缓冲区;可能还有一些。正如其他人所说的那样,评论也很缺失。
AntoineL

-1

我发现最容易使用:cd $ home \ Desktop \

将带您到当前用户桌面

就我而言,我需要检索用户名以使脚本能够更改路径,即。c:\ users \%username%。我需要通过更改用户桌面的路径来启动脚本。在上面和其他地方的帮助下,我可以使用get-location小程序来做到这一点。

您可能有另一种甚至更好的方法,但这对我有用:

$ Path =获取位置

设置位置$ Path \ Desktop


基于主目录进行任何假设都只能在非常特定的条件下进行。
劳尔·萨利纳斯-蒙塔古多

如果您在Powershell终端中工作,并且很快想知道您是什么用户,那么输入“ ls〜”应该可以解决问题。像上面的海报一样,可能会有例外,这对于脚本绝对不是很好,因此在这种情况下请使用Edouard Poor的示例。
MrBerta

-2

如果您习惯批量处理,可以致电

$user=$(cmd.exe /c echo %username%)

如果您只具有一个“ echo%username%”批处理文件,这基本上会从您得到的输出中窃取输出。


1
我之所以投票是因为:a)你$(...)是多余的:$a = cmd.exe /c echo %username%工作,b)它不是便携式的,c)它实际上并没有回答如何在powershell中做到这一点,而是回答了如何在dos中做到这一点,并且给男人一根鱼竿比给他一条鱼更好powershell puts environment variables into $env, so %username% = $env:username
kfsone

-2
  1. get-content "cm.txt"
  2. write-host "entr file name" $file = read-host get-content $file
  3. $content = get-content "cm.txt"
  4. $content = get-content "cn.txt" for each ($line in $count) {write-host $line}

$ contents = get-content“ cm.txt” ---- $ count = 0 ----- foreach($ count中的$ line)---- {$ count = $ count + 1} ----写-host“您有以下几行:” $ count
ammy,

1. $ a = $ com1,$ com2 ------写入主机“输入cm名称” ---- $ c = readhost -----写入主机$ a [$ c-1] .username ,写入主机$ a [$ c-1] .password
ammy,

$ com1 =新对象PSobject ----- $ com1 = $ com1 | 添加成员noteproperty -name用户名-value 2016
ammy

1
是否有理由将代码添加为自己的答案作为注释?
aldr

1
为什么不编辑答案并添加代码,而不是将其拆分成没有人会理解的注释?
aldr

-4

就我而言,我需要检索用户名以使脚本能够更改路径,即。c:\users\%username%\。我需要通过更改用户桌面的路径来启动脚本。在上面和其他地方的帮助下,我可以使用get-location小程序来做到这一点。

您可能有另一种甚至更好的方法,但这对我有用:

$Path = Get-Location

Set-Location $Path\Desktop

1
欢迎使用Stack Overflow!等同于Set-Location Desktop。(Get-Location仅返回当前位置,对于Set-Location具有相对路径的a而言是隐式的。)
jpaugh
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.