ChatGPT解决这个技术问题 Extra ChatGPT

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

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


P
Peter Mortensen

我找到了:

$env:UserName

还有:

$env:UserDomain
$env:ComputerName

答案只是使用 Powershell 中的静态 .NET 方法,这可能是在其他地方使用的有用技术。
当前不是登录用户,而只是环境变量!不要回答问题。
C
Chris F Carroll

在 Windows 上,您可以:

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

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

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

如果要访问环境变量:

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

[环境]::用户名——@ThomasBratt

$env:用户名——@Eoin

哇——@galaktor

如果要访问 Windows 访问令牌:

(更可靠的选择)

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

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

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

$(Get-WMIObject -class Win32_ComputerSystem | 选择用户名).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。
J
Jasper

$env:username 是最简单的方法


您可以通过这种方式分配它,并建立目录等等。
g
galaktor

我想加入 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 赢得了交互式使用。它足够短,我可以记住如何在没有咨询的情况下输入它:-)
在 Nano Server 中不是一回事。不要在脚本中使用它,做正确的事 ([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
whoami 是可执行文件。它不能从 PowerShell 中删除。它可能会从 Windows 中删除,但在非 Nano Windows Server 2012 中它仍然存在。
W
WaffleSouffle

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


P
Peter Mortensen

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

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


P
Peter Mortensen

我过去使用过 $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
P
Peter Mortensen

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

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

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

$username

第二个用户名仅在您复制和粘贴时用于显示目的。


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

我没有看到任何基于 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,这与其他示例的作用不同。
虽然这是一个新颖的代码块,但如果我知道它到底在做什么,那就太好了。你可以用评论来注释它,也许?谢谢!
我几乎想投票,因为我看到了该提案的优点。然而代码有一些缺陷:它引入了一个新的命名空间,它使用了一个魔法常数 (64),它的值不是医生规定的值(应该是 UNLEN+1,而 UNLEN 是 256),它忽略了任何可能的错误从 GetUserName 返回(通过它保留 GetLastError,这很好),它不会清理字符串缓冲区;可能还有其他一些。正如其他人所说,评论也非常缺失。
s
shaws

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

$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
K
Kes tas

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

将带您到当前用户桌面

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

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

$Path = 获取位置

设置位置 $Path\Desktop


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

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

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

$Path = Get-Location

Set-Location $Path\Desktop

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