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

Ответы:

398

Я нашел это:

$env:UserName

А также есть:

$env:UserDomain
$env:ComputerName
Томас Братт
источник
10
Быстрая и грязная альтернатива $env:username- получить имя пользователя из соответствующей переменной среды.
guillermooo
7
Я думаю, что $ env: username и [Environment] :: UserName оба указывают на одно и то же.
Кифа
16
Спасибо, что вернулись, чтобы ответить на свой вопрос. Ничего более расстраивающего, когда кто-то сам находит ответ и просто отвечает: «Неважно, понял!»
Мэтт ДиТролио
6
@MattDiTrolio Это, конечно, расстраивает, но вы думаете, нет ничего более расстраивающего, чем это ?!
Код жокея
5
@CodeJockey Ничего. Не в истории когда-либо. :)
Мэтт ДиТролио
181
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Марк Симанн
источник
16
Это наиболее безопасный ответ, потому что пользователь $env:USERNAMEможет изменить его, но это не обманет.
Кевин Панко
6
@KevinPanko Верно, но в тот момент, когда вы не можете доверять своему пользователю, есть другие, более философские вопросы, которые нужно задать. ;-)
jpaugh
4
Этот метод включает доменное имя и имя пользователя. Определенно полезно, если у вас есть несколько доменов в игре.
Райан Гейтс
Работает как положено. Проверено на резервирование адреса URL.
Марек Бар
Кроме того, это похоже на работу в PowerShell 6, а это означает, что он кросс-платформенный (.Net Standard) совместим. Думал, что стоит упомянуть, так как я задал вопрос, когда увидел пространство имен.
deadlydog
120

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

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

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

  • [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 - более надежным.

Мне пришлось использовать подход маркера доступа Windows @Mark Seemann в скрипте 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"
alexanderbird
источник
Для PowerShell 6 на Mac OS X и Linux [Environment]::UserNameэто лучший вариант, так как он работает кроссплатформенно. whoamiКажется, также работает, но зависит от whoamiинструмента, доступного на платформе.
Флориан Фельдхаус
Для Powershell 6 в Windows $env:USERNAMEвыдает, SYSTEMесли я не запускаю от имени администратора, а в [Environment]::UserName]любом случае возвращает мое имя пользователя.
kfsone
1
Похоже, что Get-WmiObjectметод больше не работает в pwsh. Даже пытался импортировать модуль совместимости и тот, Microsoft.PowerShell.Managementкоторый имеет командлет. Есть идеи, что происходит?
not2qubit
Верный. Это было уделено Get-CimInstance довольно давно по соображениям производительности ... и CIM должен использоваться поверх WMI в v6 по причинам кросс-совместимости. Если вы видите команду с GWMI, проверьте, можете ли вы вместо этого выполнять GCIM.
Хикси
105

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

Йон
источник
Вы можете назначить это таким образом, и создавать каталоги, а что нет.
Дрооганс
51

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

Write-Host "current user:"
Write-Host $(whoami)
galaktor
источник
это работает для меня на PS версии 2. Вы говорите, что он был сброшен в PS3? C: \> powershell Windows PowerShell Copyright (C) 2009 Корпорация Майкрософт. Все права защищены. PS C: \> whoami mydomain \ myusername
galaktor
2
$env:USERNAMEможет быть изменено пользователем, но это не обманет.
Кевин Панко
3
Whoami выигрывает для интерактивного использования. Он достаточно короткий, чтобы я мог вспомнить, как набирать его, не обращаясь к ТАК :-)
Иэн Сэмюэль Маклин Старший
В Nano Server нет ничего. Не используйте его в сценариях, делайте все правильно ( [System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
еще один пользователь
whoamiэто исполняемый файл. Его нельзя удалить из PowerShell. Он потенциально может быть удален из Windows, но он все еще там,
начиная с
37

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

WaffleSouffle
источник
12

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

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

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

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

Дейв Халл
источник
1
Поскольку ОП не спрашивал о Windows-Powershell, это действует, но [Environment]::UserNameменее типирование, независимо от $env:usernameи кросс-платформенный: См pastebin.com/GsfR6Hrp
kfsone
12

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

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

Эдуард Бедный
источник
10

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

[String] ${stUserDomain},[String]  ${stUserAccount} = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name.split("\")
Stef
источник
1
$username=( ( Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty username ) -split '\\' )[1]

$username

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

clayton.nichols
источник
$ fullname = Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty username $ username = $ fullname.Replace ("DOMAIN \", "") $ username
clayton.nichols
-1

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

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

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

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

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

$ Path = Get-Location

Set-Location $ Path \ Desktop

Кес тас
источник
Делать любые предположения, основанные на домашнем каталоге, обязан работать только в очень определенных условиях.
Рауль Салинас-Монтеагудо
Если вы работаете в терминале powershell и просто хотите быстро выяснить, какой вы пользователь, тогда наберите «ls ~». Как и в приведенном выше плакате, могут быть исключения, и это определенно не подходит для сценариев, поэтому в этом случае используйте пример Эдуарда Пура.
Мистер Берта
-2

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

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

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

Shaws
источник
1
Я подавляю голос, потому что: а) ты $(...)лишний: $a = cmd.exe /c echo %username%работает, б) он не переносим, ​​в) он на самом деле не отвечает на вопрос, как сделать это в 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}
Ammy
источник
$ content = get-content "cm.txt" ---- $ count = 0 ----- foreach ($ line in $ count) ---- {$ count = $ count + 1} ---- написать -host "у вас есть много строк:" $ count
ammy
1. $ a = $ com1, $ com2 ------ узел записи "введите имя cm" ---- $ c = узел чтения ----- узел записи $ a [$ c-1] .username , запись-хост $ a [$ c-1] .password
ammy
$ com1 = новый объект PSobject ----- $ com1 = $ com1 | add-member noteproperty -name имя-пользователя -значение 2016
ammy
1
Есть ли причина, по которой вы добавляете код в качестве комментариев к собственному ответу?
aldr
1
почему бы вам не отредактировать свой ответ и не добавить код вместо того, чтобы разбивать его на комментарии, подобные тем, где никто не поймет этого?
aldr
-4

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

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

$Path = Get-Location

Set-Location $Path\Desktop
KJP
источник
1
Добро пожаловать в стек переполнения ! Это эквивалентно Set-Location Desktop. ( Get-Locationпросто возвращает текущее местоположение, что неявно для Set-Locationотносительного пути.)
jpaugh