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

Posted

技术标签:

【中文标题】如何在 Windows PowerShell 中获取当前用户名?【英文标题】:How do I get the current username in Windows PowerShell? 【发布时间】:2011-01-06 08:15:02 【问题描述】:

【问题讨论】:

【参考方案1】:

我找到了:

$env:UserName

还有:

$env:UserDomain
$env:ComputerName

【讨论】:

答案只是使用 Powershell 中的静态 .NET 方法,这可能是在其他地方使用的有用技术。 当前没有登录用户,只是环境变量!不要回答问题。【参考方案2】:

在 Windows 上,您可以:

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

【讨论】:

这是最安全的答案,因为$env:USERNAME 可以由用户更改,但不会因此而被愚弄。 @KevinPanko 是的,但是在您无法信任您的用户的时候,还有其他更哲学的问题需要问。 ;-) 这个方法包括域名和用户名。如果您有多个域在使用,这绝对是有益的。 按预期工作。已测试 url 地址预留。 此外,这看起来也适用于 PowerShell 6,这意味着它与跨平台(.Net 标准)兼容。觉得值得一提,因为我看到命名空间就质疑了。【参考方案3】:

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

如果你想访问environment variable

(更容易/更短/难忘的选择)

[Environment]::UserName -- @ThomasBratt $env:username -- @Eoin whoami -- @galaktor

如果你想访问Windows access token

(更可靠的选择)

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

如果你想要登录用户的名字

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

$(Get-WMIObject -class Win32_ComputerSystem | select username).username -- @TwonOfAn on this other forum

比较

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

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

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

我不得不在一个 PowerShell 脚本中使用 @Mark Seemann 的 Windows 访问令牌方法,该脚本是通过模拟 C# 应用程序运行的。

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 工具。 对于 Windows 上的 Powershell 6,$env:USERNAME 生成 SYSTEM,除非我以管理员身份运行,而 [Environment]::UserName] 生成我的用户名。 似乎Get-WmiObject 方法不再适用于 pwsh。甚至尝试导入兼容性模块和具有 cmdlet 的 Microsoft.PowerShell.Management。知道发生了什么吗? 正确。由于性能原因,Get-CimInstance 很长一段时间前都被它所困扰......并且出于交叉兼容性的原因,CIM 必须在 v6 中用于 WMI。如果您看到带有 GWMI 的命令,请检查您是否可以改为执行 GCIM。【参考方案4】:

$env:username 是最简单的方法

【讨论】:

你可以这样分配它,建立目录等等。【参考方案5】:

我想输入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 $env:USERNAME 可以由用户更改,但这样做不会被愚弄。 whoami 在交互式使用中获胜。它足够短,我可以记住如何在不咨询 SO 的情况下输入它:-) 在 Nano Server 中不是一个东西。不要在脚本中使用它,做正确的事情([System.Security.Principal.WindowsIdentity]::GetCurrent().Name whoami 是一个可执行文件。它不能从 PowerShell 中删除。它可能会从 Windows 中删除,但在非 Nano Windows Server 2012 中它仍然存在。【参考方案6】:

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

【讨论】:

【参考方案7】:

现在PowerShell Core(又名v6)已经发布,人们可能想编写跨平台脚本,这里的许多答案在Windows以外的任何东西上都不起作用。

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

【讨论】:

【参考方案8】:

我过去使用过$env:username,但一位同事指出它是一个环境变量,可以由用户更改,因此,如果你真的想获取当前用户的用户名,你不应该相信它。

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

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

我不会使用 whoami.exe,因为它并非出现在所有版本的 Windows 上,而且它是对另一个二进制文件的调用,可能会让一些安全团队适应。

【讨论】:

既然 OP 确实询问过 Windows-Powershell,那是有效的,但 [Environment]::UserName 打字较少,独立于 $env:username 和跨平台:参见 pastebin.com/GsfR6Hrp【参考方案9】:

这里只是建立在其他人的工作之上:

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

【讨论】:

【参考方案10】:
$username=( ( Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty username ) -split '\\' )[1]

$username

second username 仅在您复制和粘贴时用于显示目的。

【讨论】:

$fullname=Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty username $username=$fullname.Replace("DOMAIN\","") $username 如果您希望用户登录到机器,而不是运行 powershell 会话的用户,这个方法效果最好。如果您正在以系统身份运行脚本并想知道哪个用户登录到计算机,则环境变量无济于事。 根据我的调查,似乎最好使用Get-CIMInstance 而不是Get-WMIObject。请参考文章here。【参考方案11】:

我没有看到任何基于 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()

【讨论】:

请解释这段代码在做什么以及为什么它比一种较短的方法更有用。 @BenjaminHubbard 这个问题不是问最短的方法,而是问如何用 powershell 完成壮举。通过调用 dll 中的函数并使用 Add-Type 方法访问 .NET,这与其他示例的作用不同。 虽然这是一个新颖的代码块,但如果我知道它到底在做什么,那就太好了。你能用 cmets 注释它吗?谢谢! 我几乎想投票,因为我看到了该提案的优点。然而代码有一些缺陷:它引入了一个新的命名空间,它使用了一个魔法常数(64),它的值不是医生规定的(应该是UNLEN+1UNLEN 是 256),它忽略了任何可能的错误从 GetUserName 返回(通过它保留 GetLastError,这很好),它不会清理字符串缓冲区;可能还有其他一些。正如其他人所说,cmets 也非常失踪。【参考方案12】:

如果你习惯批处理,可以调用

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

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

【讨论】:

我投反对票是因为:a)你的 $(...) 是多余的:$a = cmd.exe /c echo %username% 有效,b)它不可移植,c)它实际上并没有回答如何做到这一点的问题在powershell中,它回答了如何在dos中进行操作,并且最好给一个人鱼竿而不是给他一条鱼,例如powershell puts environment variables into $env, so %username% = $env:username.【参考方案13】:

我觉得最容易使用:cd $home\Desktop\

将带您到当前用户桌面

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

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

$Path = 获取位置

设置位置 $Path\Desktop

【讨论】:

根据主目录做出任何假设都只能在非常特定的条件下工作。 如果您在 powershell 终端中工作并且只是想快速找出您是什么用户,那么键入“ls ~”应该可以解决问题。像上面的海报一样,可能会有例外,这对脚本来说肯定是不好的,所以在这种情况下使用 Edouard Poor 的例子。【参考方案14】:

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

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

$Path = Get-Location

Set-Location $Path\Desktop

【讨论】:

欢迎来到Stack Overflow!这相当于Set-Location Desktop。 (Get-Location 仅返回当前位置,这对于具有相对路径的 Set-Location 是隐含的。)

以上是关于如何在 Windows PowerShell 中获取当前用户名?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Powershell 中为“网络服务”帐户创建 Windows 服务?

windows powershell 如何进入文件目录

如何使用 Windows 窗体在列表视图中显示 PowerShell 输出

如何在具有管理员权限的 Windows 任务计划程序中设置 Powershell 脚本?

如何在 powershell 中检测 Linux 或 macOS 或 Windows?

如何使用PowerShell管理Windows服务