Как мне получить текущее имя пользователя в Windows PowerShell?

Как мне получить текущее имя пользователя в Windows PowerShell?


person Thomas Bratt    schedule 18.01.2010    source источник


Ответы (14)


Я нашел это:

$env:UserName

Есть также:

$env:UserDomain
$env:ComputerName
person Thomas Bratt    schedule 18.01.2010
comment
Быстрая и грязная альтернатива - $env:username получить имя пользователя из соответствующей переменной среды. - person guillermooo; 21.01.2010
comment
Я думаю, что $ env: username и [Environment] :: UserName указывают на одно и то же. - person Cephas; 22.01.2010
comment
Ответ заключается в использовании статического метода .NET из Powershell, который может оказаться полезным для использования в другом месте. - person Thomas Bratt; 28.07.2011
comment
Спасибо, что вернулись, чтобы ответить на свой вопрос. Нет ничего более разочаровывающего, когда кто-то сам находит ответ и просто отвечает: «Неважно, понял! - person Matt DiTrolio; 03.05.2012
comment
Не зарегистрированный пользователь, а просто переменные среды! Не отвечайте на вопрос. - person MUY Belgium; 06.05.2015
comment
@MattDiTrolio Это определенно расстраивает, но ты думаешь, что ничего расстраивает больше, чем это ?! - person Code Jockey; 23.07.2015
comment
@CodeJockey Ничего. Ни разу в истории. :) - person Matt DiTrolio; 23.07.2015
comment
@kfsone: ваш pastebin - самая полная ссылка на этой странице. Должен быть ответ. - person Nick Cox; 13.04.2019
comment
Может быть, пользователь знает, что он делает, и у него есть веские причины для смены имени пользователя, и вам не следует мешать ему? - person john v kumpf; 23.07.2021

Я подумал, что было бы полезно обобщить и сравнить полученные ответы.

Если вы хотите получить доступ к переменной среды:

(вариант проще / короче / запоминающийся)

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

Если вы хотите получить доступ к Токен доступа Windows:

(более надежный вариант)

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

Если вы хотите, чтобы имя вошедшего в систему пользователя

(а не имя пользователя, запустившего экземпляр PowerShell)


Сравнение

Комментарий @Kevin Panko к ответу @Mark Seemann касается выбора одной из категорий над другой:

[Подход с использованием токена доступа Windows] является наиболее безопасным ответом, потому что $ env: USERNAME может быть изменено пользователем, но это не обманет вас.

Короче говоря, параметр переменной среды более лаконичен, а параметр токена доступа Windows более надежен.

Мне пришлось использовать подход @Mark Seemann к токену доступа Windows в сценарии PowerShell, который я запускал из приложения C # с олицетворением.

Приложение C # запускается с моей учетной записью пользователя и запускает сценарий PowerShell как учетную запись службы. Из-за ограничений способа запуска сценария PowerShell из C # экземпляр PowerShell использует переменные среды моей учетной записи, даже если он запускается как пользователь учетной записи службы.

В этой настройке параметры переменной среды возвращают имя моей учетной записи, а параметр токена доступа Windows возвращает имя учетной записи службы (это то, что я хотел), а параметр вошедшего в систему пользователя возвращает имя моей учетной записи.


Тестирование

Кроме того, если вы хотите самостоятельно сравнить параметры, вот сценарий, который вы можете использовать для запуска сценария от имени другого пользователя. Вам необходимо использовать командлет Get-Credential для получения объекта учетных данных, а затем запустить этот сценарий со сценарием для запуска от имени другого пользователя в качестве аргумента 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"
person alexanderbird    schedule 29.04.2015
comment
Для PowerShell 6 в Mac OS X и Linux [Environment]::UserName - лучший вариант, поскольку он работает на разных платформах. whoami, похоже, тоже работает, но зависит от whoami инструмента, доступного на платформе. - person Florian Feldhaus; 18.01.2018
comment
Для Powershell 6 в Windows $env:USERNAME создает SYSTEM, если я не запускаю его от имени администратора, а [Environment]::UserName] в любом случае возвращает мое имя пользователя. - person kfsone; 25.07.2018
comment
Похоже, что метод Get-WmiObject больше не работает в pwsh. Даже пытался импортировать модуль совместимости и Microsoft.PowerShell.Management, в котором есть командлет. Есть идеи, что происходит? - person not2qubit; 04.02.2019
comment
Верный. Некоторое время назад он был сбит с толку Get-CimInstance по соображениям производительности ... а CIM должен использоваться поверх WMI в v6 по причинам кросс-совместимости. Если вы видите команду с GWMI, проверьте, можете ли вы вместо этого выполнить GCIM. - person Hicsy; 04.09.2019

$env:username это самый простой способ

person Eoin    schedule 14.10.2011
comment
Вы можете назначить это таким образом, и создавать каталоги, а что нет. - person Droogans; 28.08.2012

Я хотел бы добавить команду whoami, которая в основном является хорошим псевдонимом для выполнения %USERDOMAIN%\%USERNAME%, как предлагается в других ответах.

Write-Host "current user:"
Write-Host $(whoami)
person galaktor    schedule 14.11.2011
comment
у меня он работает на PS версии 2. Вы говорите, что он был сброшен на PS3? C: \ ›powershell Windows PowerShell Copyright (C) 2009 Microsoft Corporation. Все права защищены. PS C: \ ›whoami mydomain \ myusername - person galaktor; 09.10.2013
comment
$env:USERNAME может быть изменен пользователем, но это не обманет его. - person Kevin Panko; 24.04.2014
comment
whoami выигрывает для интерактивного использования. Он достаточно короткий, чтобы я мог вспомнить, как его набирать, не консультируясь с SO :-) - person Iain Samuel McLean Elder; 22.08.2014
comment
Ничего подобного в Nano Server. Не используйте его в скриптах, делайте правильные вещи ([System.Security.Principal.WindowsIdentity]::GetCurrent().Name) - person Yet Another User; 17.10.2016
comment
whoami - исполняемый файл. Его нельзя удалить из PowerShell. Потенциально он может быть удален из Windows, но он все еще присутствует в Windows Server 2012, отличном от Nano. - person jpmc26; 11.03.2017
comment
У whoami есть дополнительное преимущество: он может возвращать UPN на компьютере, присоединенном к Azure AD, для которого% USERNAME% мало используется. Например, $ Env: Username возвращает RobNicholson, но мое имя пользователя Azure AD действительно [email protected] - person Rob Nicholson; 24.10.2018
comment
Обратите внимание, что если вы используете систему удаленного управления, которая может использовать сценарии Powershell, whoami вернет SYSTEM, а не пользователя, вошедшего в систему. - person LPChip; 09.11.2018

[Environment]::UserName возвращает только имя пользователя. Например. bob [System.Security.Principal.WindowsIdentity]::GetCurrent().Name возвращает имя пользователя с префиксом домена, где это необходимо. Например. SOMEWHERENICE \ bob

person WaffleSouffle    schedule 14.07.2011

Теперь, когда выпущено PowerShell Core (также известное как v6), люди могут захотеть напишите кросс-платформенные скрипты, многие ответы здесь не будут работать ни на чем, кроме Windows.

[Environment]::UserName, по-видимому, является лучшим способом получить текущее имя пользователя на всех платформах, поддерживаемых PowerShell Core, если вы не хотите добавлять в свой код определение платформы и специальный регистр.

person Edouard Poor    schedule 15.03.2018

Раньше я использовал $env:username, но коллега указал, что это переменная среды, которая может быть изменена пользователем, поэтому, если вы действительно хотите получить имя пользователя текущего пользователя, вам не следует доверять ему.

Я бы поддержал ответ Марка Симанна: [System.Security.Principal.WindowsIdentity] :: GetCurrent (). Name

Но мне не разрешено. С ответом Марка, если вам нужно только имя пользователя, вам, возможно, придется проанализировать его, поскольку в моей системе он возвращает hostname\username, а на подключенных к домену машинах с учетными записями домена он возвращает domain\username.

Я бы не стал использовать whoami.exe, поскольку он присутствует не во всех версиях Windows, и это вызов другого двоичного файла, который может подойти некоторым группам безопасности.

person Dave Hull    schedule 24.01.2017
comment
Поскольку OP действительно спрашивал о Windows-Powershell, это верно, но [Environment]::UserName меньше набирает, независимо от $env:username и кроссплатформенности: см. pastebin.com/GsfR6Hrp - person kfsone; 23.09.2018

Просто опираясь на работу других здесь:

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

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

$username

второе имя пользователя используется только для отображения, только если вы скопируете и вставите его.

person clayton.nichols    schedule 06.06.2019
comment
$ fullname = Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty имя пользователя $ username = $ fullname.Replace (DOMAIN \,) $ username - person clayton.nichols; 06.06.2019
comment
Этот вариант работает лучше всего, если вы хотите, чтобы пользователь вошел в систему на машине, а не пользователь, запустивший сеанс PowerShell. Если вы запускаете сценарий как систему и хотите знать, какой пользователь вошел в систему, переменные env не помогают. - person KeetsScrimalittle; 05.08.2020

Я не видел никаких Add-Type на основе примеров. Вот тот, который использует GetUserName непосредственно из 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()
person Knuckle-Dragger    schedule 03.08.2014
comment
Пожалуйста, объясните, что делает этот код и почему он может быть полезнее одного из более коротких методов. - person Benjamin Hubbard; 09.04.2015
comment
@BenjaminHubbard Вопрос не требует кратчайшего метода, он спрашивает, как выполнить подвиг с помощью PowerShell. Этот трюк отличается от других примеров, вызывая функцию внутри dll и используя метод Add-Type для доступа к .NET. - person Knuckle-Dragger; 25.07.2015
comment
Хотя это новый блок кода, было бы здорово, если бы я знал, что он, черт возьми, делает. Может быть, вы можете аннотировать это комментариями? Спасибо! - person jpaugh; 18.01.2016
comment
Я почти хотел проголосовать за, так как увидел в предложении достоинства. Тем не менее, код имеет некоторые недостатки: он вводит новое пространство имен, он использует магическую константу (64), значение которой не соответствует предписанию врача (должно быть UNLEN+1, а UNLEN равно 256), он игнорирует любые ошибки, которые могут быть возвращены из GetUserName. (из-за того, что сохраняет GetLastError, хороший момент), он не очищает строковый буфер; и, возможно, некоторые другие. И, как говорили другие, комментариев тоже очень не хватает. - person AntoineL; 10.05.2017

Если вы привыкли к пакетной обработке, вы можете позвонить

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

Это в основном крадет вывод из того, что вы получили бы, если бы у вас был командный файл только с "echo% username%".

person shaws    schedule 06.07.2017
comment
Я голосую против, потому что: а) вы $(...) лишнее: $a = cmd.exe /c echo %username% работает, б) он не переносится, в) он фактически не отвечает на вопрос, как это сделать в PowerShell, он отвечает, как это сделать в dos, и лучше дать человеку удочку, чем рыбу, например powershell puts environment variables into $env, so %username% = $env:username. - person kfsone; 23.09.2018

Я считаю, что проще всего использовать: cd $ home \ Desktop \

перенесет вас на рабочий стол текущего пользователя

В моем случае мне нужно было получить имя пользователя, чтобы сценарий мог изменить путь, т.е. c: \ users \% username%. Мне нужно было запустить скрипт, изменив путь к рабочему столу пользователя. Я смог сделать это с помощью сверху и из других источников, используя апплет get-location.

У вас может быть другой или даже лучший способ сделать это, но у меня это сработало:

$ Path = Get-Location

Set-Location $ Путь \ Рабочий стол

person Kes tas    schedule 01.02.2019
comment
Любые предположения, основанные на домашнем каталоге, будут работать только при очень определенных условиях. - person Raúl Salinas-Monteagudo; 26.06.2019
comment
Если вы работаете в терминале PowerShell и просто хотите быстро узнать, какой вы пользователь, наберите ls ~. Как и на плакате выше, могут быть исключения, и это определенно не подходит для сценариев, поэтому используйте в этом случае пример Эдуарда Пура. - person MrBerta; 24.09.2019

В моем случае мне нужно было получить имя пользователя, чтобы сценарий мог изменить путь, т.е. c:\users\%username%\. Мне нужно было запустить скрипт, изменив путь к рабочему столу пользователя. Я смог сделать это с помощью сверху и из других источников с помощью апплета get-location.

У вас может быть другой или даже лучший способ сделать это, но у меня это сработало:

$Path = Get-Location

Set-Location $Path\Desktop
person kjp    schedule 30.12.2015
comment
Добро пожаловать в Stack Overflow! Это эквивалент Set-Location Desktop. (Get-Location просто возвращает текущее местоположение, что неявно для Set-Location с относительным путем.) - person jpaugh; 18.01.2016

person    schedule
comment
Это наиболее безопасный ответ, потому что $env:USERNAME может быть изменен пользователем, но это не обманет его. - person Kevin Panko; 24.04.2014
comment
@KevinPanko Верно, но в тот момент, когда вы не можете доверять своему пользователю, нужно задать другие, более философские вопросы. ;-) - person jpaugh; 18.01.2016
comment
Этот метод включает имя домена и имя пользователя. Определенно выгодно, если у вас в игре несколько доменов. - person Ryan Gates; 16.02.2016
comment
Работает как положено. Протестировано на резервирование URL-адреса. - person Marek Bar; 06.07.2018
comment
Кроме того, похоже, что это работает и в PowerShell 6, что означает, что он совместим с кросс-платформой (.Net Standard). Подумал, что об этом стоит упомянуть, так как я усомнился в этом, когда увидел пространство имен. - person deadlydog; 04.12.2019