Jak uzyskać bieżącą nazwę użytkownika w programie Windows PowerShell?

324

Jak uzyskać bieżącą nazwę użytkownika w programie Windows PowerShell?

Thomas Bratt
źródło

Odpowiedzi:

397

Znalazłem to:

$env:UserName

Jest również:

$env:UserDomain
$env:ComputerName
Thomas Bratt
źródło
10
Szybką i brudną alternatywą byłoby $env:usernamepobranie nazwy użytkownika z odpowiedniej zmiennej środowiskowej.
guillermooo,
7
Myślę, że $ env: nazwa użytkownika i [Środowisko] :: nazwa_użytkownika wskazują na to samo.
Cefas
16
Dziękujemy za przyjście i udzielenie odpowiedzi na własne pytanie. Nic bardziej frustrującego, gdy ktoś sam wymyśli odpowiedź i po prostu odpowie: „Nieważne, rozumiem!”
Matt DiTrolio
6
@MattDiTrolio To z pewnością jest frustrujące, ale uważasz, że nie ma nic bardziej frustrującego niż to ?!
Code Jockey
5
@CodeJockey Nic. Nigdy w historii. :)
Matt DiTrolio,
180
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Mark Seemann
źródło
16
Jest to najbezpieczniejsza odpowiedź, ponieważ $env:USERNAMEmoże zostać zmieniona przez użytkownika, ale nie da się tego oszukać.
Kevin Panko
6
@KevinPanko To prawda, ale w momencie, gdy nie możesz ufać swojemu użytkownikowi, musisz zadać inne, bardziej filozoficzne pytania. ;-)
jpaugh
4
Ta metoda obejmuje nazwę domeny i nazwę użytkownika. Zdecydowanie korzystne, jeśli masz wiele domen w grze.
Ryan Gates
Działa zgodnie z oczekiwaniami. Przetestowano pod kątem rezerwacji adresu URL.
Marek Bar
Wygląda na to, że działa również w PowerShell 6, co oznacza, że ​​jest kompatybilny z wieloma platformami (.Net Standard). Pomyślałem, że warto o tym wspomnieć, ponieważ przesłuchałem go, gdy zobaczyłem przestrzeń nazw.
deadlydog,
120

Pomyślałem, że warto podsumować i porównać podane odpowiedzi.

Jeśli chcesz uzyskać dostęp do zmiennej środowiskowej :

(łatwiejsza / krótsza / zapadająca w pamięć opcja)

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

Jeśli chcesz uzyskać dostęp do tokena dostępu do systemu Windows :

(bardziej niezawodna opcja)

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

Jeśli chcesz podać nazwę zalogowanego użytkownika

(zamiast nazwy użytkownika uruchamiającego instancję PowerShell)

  • $(Get-WMIObject -class Win32_ComputerSystem | select username).username- @TwonOfAn na tym innym forum

Porównanie

Komentarz @Kevin Panko do odpowiedzi @Mark Seemann dotyczy wyboru jednej z kategorii zamiast drugiej:

[Podejście do tokena dostępu do systemu Windows] jest najbezpieczniejszą odpowiedzią, ponieważ $ env: USERNAME może zostać zmieniony przez użytkownika, ale nie da się tego oszukać.

Krótko mówiąc, opcja zmiennej środowiskowej jest bardziej zwięzła, a opcja tokena dostępu do systemu Windows jest bardziej niezawodna.

Musiałem używać podejścia @Mark Seemann do tokena dostępu do systemu Windows w skrypcie PowerShell, który uruchamiałem z aplikacji C # z personifikacją.

Aplikacja C # jest uruchamiana z moim kontem użytkownika i uruchamia skrypt PowerShell jako konto usługi. Z powodu ograniczenia sposobu uruchamiania skryptu PowerShell z C #, instancja PowerShell używa zmiennych środowiskowych mojego konta użytkownika, nawet jeśli jest uruchamiana jako użytkownik konta usługi.

W tym ustawieniu opcje zmiennej środowiskowej zwracają nazwę mojego konta, a opcja tokena dostępu do systemu Windows zwraca nazwę konta usługi (czego chciałem), a zalogowana opcja użytkownika zwraca nazwę mojego konta.


Testowanie

Ponadto, jeśli chcesz porównać opcje samodzielnie, oto skrypt, którego możesz użyć do uruchomienia skryptu jako inny użytkownik. Aby uzyskać obiekt referencji, należy użyć polecenia cmdlet Get-Credential, a następnie uruchomić ten skrypt ze skryptem, aby uruchomić jako inny użytkownik jako argument 1, a obiekt referencji jako argument 2.

Stosowanie:

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

Zawartość skryptu 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
źródło
Dla PowerShell 6 na Mac OS X i Linux [Environment]::UserNamejest najlepszą opcją, ponieważ działa na wielu platformach. whoamiwydaje się również działać, ale zależy od whoaminarzędzia dostępnego na platformie.
Florian Feldhaus
W przypadku programu Powershell 6 w systemie Windows $env:USERNAMEprodukuje, SYSTEMchyba że uruchomię się jako administrator, a jednocześnie podaje [Environment]::UserName]moją nazwę użytkownika.
kfsone
1
Wydaje się, że Get-WmiObjectmetoda nie działa już w pwsh. Próbowałem nawet zaimportować moduł zgodności i ten, Microsoft.PowerShell.Managementktóry ma polecenie cmdlet. Masz pomysł, co się dzieje?
not2qubit
Poprawny. Został on przełożony na Get-CimInstance dość dawno temu ze względu na wydajność ... i CIM musi być używany przez WMI w v6 ze względu na kompatybilność. Jeśli zobaczysz polecenie z GWMI, sprawdź, czy możesz zamiast tego zrobić GCIM.
Hicsy
105

$env:username jest najprostszym sposobem

Eoin
źródło
Możesz to przypisać w ten sposób i budować katalogi, a co nie.
Droogans
51

Chciałbym wrzucić komendę whoami , która w zasadzie jest fajnym pseudonimem do działania, %USERDOMAIN%\%USERNAME%jak zaproponowano w innych odpowiedziach.

Write-Host "current user:"
Write-Host $(whoami)
galaktor
źródło
działa dla mnie na PS w wersji 2. Czy mówisz, że został upuszczony na PS3? C: \> powershell Windows PowerShell Copyright (C) 2009 Microsoft Corporation. Wszelkie prawa zastrzeżone. PS C: \> whoami mydomain \ myusername
galaktor
2
$env:USERNAMEmoże zostać zmieniony przez użytkownika, ale nie da się tego oszukać.
Kevin Panko
3
whoami wygrywa za interaktywne użycie. Jest na tyle krótki, że pamiętam, jak go wpisać bez konsultacji SO :-)
Iain Samuel McLean Starszy
Nic w Nano Server. Nie używaj go w skryptach, rób właściwą rzecz ( [System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
Yet Another User
whoamijest plikiem wykonywalnym. Nie można go usunąć z PowerShell. Można go potencjalnie usunąć z systemu Windows, ale nadal jest dostępny od wersji innej niż Nano Windows Server 2012.
jpmc26
37

[Environment]::UserNamezwraca tylko nazwę użytkownika. Np. Bob [System.Security.Principal.WindowsIdentity]::GetCurrent().Name zwraca nazwę użytkownika, w razie potrzeby poprzedzoną jej domeną. Np. SOMEWHERENICE \ bob

Wafel Suflet
źródło
12

Używałem $env:usernamew przeszłości, ale kolega z pracy zauważył, że jest to zmienna środowiskowa i może być zmieniona przez użytkownika, dlatego jeśli naprawdę chcesz uzyskać nazwę użytkownika bieżącego użytkownika, nie powinieneś jej ufać.

Głosowałbym za odpowiedzią Marka Seemanna: [System.Security.Principal.WindowsIdentity] :: GetCurrent (). Nazwa

Ale nie wolno mi. Z odpowiedzią Marka, jeśli potrzebujesz tylko nazwy użytkownika, być może będziesz musiał ją przeanalizować, ponieważ w moim systemie ona zwraca, hostname\usernamea na komputerach przyłączonych do domeny z kontami domeny to zwróci domain\username.

Nie użyłbym tego, whoami.exeponieważ nie jest obecny we wszystkich wersjach systemu Windows, a jest to wezwanie do innego pliku binarnego i może dać atak zespołom bezpieczeństwa.

Dave Hull
źródło
1
Ponieważ OP zapytał o Windows PowerShell, jest to poprawne, ale [Environment]::UserNamejest mniej $env:username
typowe
12

Teraz ten rdzeń PowerShell wydaniu (aka v6), a ludzie mogą chcieć pisać skrypty wieloplatformowe, wiele odpowiedzi tutaj nie będzie działać na niczym innym niż Windows.

[Environment]::UserName wydaje się być najlepszym sposobem na uzyskanie bieżącej nazwy użytkownika na wszystkich platformach obsługiwanych przez PowerShell Core, jeśli nie chcesz dodawać wykrywania kodu i specjalnej obudowy do swojego kodu.

Edouard Poor
źródło
10

Opierając się tylko na pracy innych tutaj:

[String] ${stUserDomain},[String]  ${stUserAccount} = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name.split("\")
Stef
źródło
1
$username=( ( Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty username ) -split '\\' )[1]

$username

Druga nazwa jest tylko do wyświetlania celów wyłącznie jeśli skopiować i wkleić.

clayton.nichols
źródło
$ fullname = Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty nazwa użytkownika $ nazwa użytkownika = $ pełna nazwa. Wymień („DOMENA \”, „”) $ nazwa użytkownika
clayton.nichols
-1

Nie widziałem żadnych przykładów opartych na Add-Type . Oto jeden za pomocą GetUserName bezpośrednio z 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
źródło
1
Wyjaśnij, co robi ten kod i dlaczego byłby bardziej użyteczny niż jedna z krótszych metod.
Benjamin Hubbard,
@BenjaminHubbard Pytanie nie wymaga najkrótszej metody, pyta, jak dokonać wyczynu za pomocą programu PowerShell. Robi to inaczej niż w innych przykładach, wywołując funkcję wewnątrz biblioteki DLL i używając metody Add-Type, aby uzyskać dostęp do .NET.
Knuckle-Dragger
1
Chociaż jest to nowatorski blok kodu, byłoby wspaniale, gdybym wiedział, co do cholery robi. Czy możesz to opatrzyć komentarzami? Dzięki!
jpaugh
1
Niemal chciałem głosować, ponieważ dostrzegłem wartość wniosku. Jednak kod ma kilka wad: wprowadza nową przestrzeń nazw, wykorzystuje stałą magiczną (64), których wartość nie jest to, co lekarz przepisał (powinno być UNLEN+1, a UNLENjest 256), to pomija żadnego błędu, który mógłby zostać zwrócony z GetUserName (poprzez zachowuje GetLastError, co jest dobrym punktem), nie czyści bufora ciągów; i prawdopodobnie kilka innych. I jak powiedzieli inni, bardzo brakuje też komentarzy.
AntoineL
-1

Uważam, że najłatwiejszy w użyciu: cd $ home \ Desktop \

zabierze Cię do bieżącego pulpitu użytkownika

W moim przypadku musiałem pobrać nazwę użytkownika, aby umożliwić skryptowi zmianę ścieżki, tj. c: \ users \% nazwa użytkownika%. Musiałem uruchomić skrypt, zmieniając ścieżkę do pulpitu użytkownika. Byłem w stanie to zrobić, korzystając z pomocy z góry i gdzie indziej, używając apletu get-location.

Możesz mieć inny, a nawet lepszy sposób, aby to zrobić, ale to zadziałało dla mnie:

$ Path = Get-Location

Ustaw lokalizację $ Path \ Desktop

Kes tas
źródło
Dokonywanie jakichkolwiek założeń w oparciu o katalog domowy musi działać tylko w ściśle określonych warunkach.
Raúl Salinas-Monteagudo
Jeśli pracujesz w terminalu PowerShell i po prostu chcesz szybko dowiedzieć się, jakim jesteś użytkownikiem, wpisz „ls ~”. Podobnie jak powyższy plakat, mogą istnieć wyjątki i to zdecydowanie nie jest dobre dla skryptów, więc skorzystaj z przykładu Edouarda Poor'a w tym przypadku.
MrBerta
-2

Jeśli jesteś przyzwyczajony do partii, możesz zadzwonić

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

To w zasadzie kradnie dane wyjściowe z tego, co byś otrzymał, gdybyś miał plik wsadowy z po prostu „echo% nazwa użytkownika%”.

Shaws
źródło
1
Głosuję za odrzuceniem, ponieważ: a) Ty jesteś $(...)zbyteczny: $a = cmd.exe /c echo %username%działa, b) nie jest przenośny, c) tak naprawdę nie odpowiada na pytanie, jak to zrobić w PowerShell, odpowiada, jak to zrobić w dos, i to jest lepiej dać mężczyźnie wędkę niż dać mu rybę, np 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
źródło
$ content = get-content "cm.txt" ---- $ count = 0 ----- foreach ($ line in $ count) ---- {$ count = $ count + 1} ---- write -host ”masz wiele wierszy:„ $ count
ammy
1. $ a = $ com1, $ com2 ------ write-host "wprowadź cm name" ---- $ c = readhost ----- write-host $ a [$ c-1]. Nazwa użytkownika , napisz host $ a [$ c-1]. hasło
ammy
$ com1 = nowy obiekt PSobject ----- $ com1 = $ com1 | add-member noteproperty -name nazwa użytkownika-wartość 2016
ammy
1
czy istnieje powód, dla którego dodajesz kod jako komentarz do własnej odpowiedzi?
dniu
1
dlaczego nie edytujesz swojej odpowiedzi i nie dodajesz kodu zamiast dzielenia go na takie komentarze, w których nikt go nie zrozumie?
aldr
-4

W moim przypadku musiałem pobrać nazwę użytkownika, aby umożliwić skryptowi zmianę ścieżki, tj. c:\users\%username%\. Musiałem uruchomić skrypt, zmieniając ścieżkę do pulpitu użytkownika. Byłem w stanie to zrobić, korzystając z pomocy z góry i gdzie indziej, używając get-location apletu .

Możesz mieć inny, a nawet lepszy sposób, aby to zrobić, ale to zadziałało dla mnie:

$Path = Get-Location

Set-Location $Path\Desktop
kjp
źródło
1
Witamy w Stack Overflow ! Jest to równoważne z Set-Location Desktop. ( Get-Locationjedynie zwraca bieżącą lokalizację, która jest domyślna dla Set-Locationścieżki względnej.)
jpaugh