Bagaimana cara mendapatkan nama pengguna saat ini di Windows PowerShell?

324

Bagaimana cara mendapatkan nama pengguna saat ini di Windows PowerShell?

Thomas Bratt
sumber

Jawaban:

398

Aku menemukannya:

$env:UserName

Ada juga:

$env:UserDomain
$env:ComputerName
Thomas Bratt
sumber
10
Alternatif cepat dan kotor adalah $env:usernamemengambil nama pengguna dari variabel lingkungan yang sesuai.
guillermooo
7
Saya pikir $ env: nama pengguna dan [Lingkungan] :: UserName menunjuk ke hal yang sama.
Cephas
16
Terima kasih telah kembali untuk menjawab pertanyaan Anda sendiri. Tidak ada yang lebih membuat frustrasi ketika seseorang menemukan jawabannya sendiri dan hanya menjawab, "Sudahlah, mengerti!"
Matt DiTrolio
6
@MattDiTrolio Itu memang membuat frustrasi, tapi Anda pikir tidak ada yang lebih menyebalkan dari itu ?!
Code Jockey
5
@CodeJockey Tidak ada. Tidak dalam sejarah. :)
Matt DiTrolio
181
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Mark Seemann
sumber
16
Ini adalah jawaban yang paling aman karena $env:USERNAMEdapat diubah oleh pengguna, tetapi ini tidak akan dibodohi dengan melakukan itu.
Kevin Panko
6
@KevinPanko Benar, tetapi pada saat Anda tidak dapat mempercayai pengguna Anda, ada pertanyaan lain yang lebih filosofis yang perlu ditanyakan. ;-)
jpaugh
4
Metode ini mencakup nama domain dan nama pengguna. Pasti bermanfaat jika Anda memiliki banyak domain dalam permainan.
Ryan Gates
Bekerja seperti yang diharapkan. Diuji untuk reservasi alamat url.
Marek Bar
Selain itu, ini juga berfungsi di PowerShell 6, yang berarti kompatibel dengan platform lintas (Standar Bersih). Pikir itu layak disebutkan karena saya mempertanyakannya ketika saya melihat namespace.
deadlydog
120

Saya pikir akan sangat berharga untuk merangkum dan membandingkan jawaban yang diberikan.

Jika Anda ingin mengakses variabel lingkungan :

(opsi lebih mudah / pendek / mudah diingat)

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

Jika Anda ingin mengakses token akses Windows :

(opsi yang lebih bisa diandalkan)

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

Jika Anda ingin nama pengguna yang masuk

(bukan nama pengguna yang menjalankan instance PowerShell)

  • $(Get-WMIObject -class Win32_ComputerSystem | select username).username- @TwonOfAn di forum lain ini

Perbandingan

Komentar @Kevin Panko pada jawaban @Mark Seemann berkaitan dengan memilih salah satu kategori di atas yang lain:

[Pendekatan token akses Windows] adalah jawaban yang paling aman, karena $ env: USERNAME dapat diubah oleh pengguna, tetapi ini tidak akan dibodohi dengan melakukan itu.

Singkatnya, opsi variabel lingkungan lebih ringkas, dan opsi token akses Windows lebih dapat diandalkan.

Saya harus menggunakan pendekatan token akses @Mark Seemann dalam skrip PowerShell yang saya jalankan dari aplikasi C # dengan peniruan.

Aplikasi C # dijalankan dengan akun pengguna saya, dan menjalankan skrip PowerShell sebagai akun layanan. Karena keterbatasan cara saya menjalankan skrip PowerShell dari C #, contoh PowerShell menggunakan variabel lingkungan akun pengguna saya, meskipun dijalankan sebagai pengguna akun layanan.

Dalam pengaturan ini, opsi variabel lingkungan mengembalikan nama akun saya, dan opsi token akses Windows mengembalikan nama akun layanan (yang saya inginkan), dan opsi pengguna yang masuk mengembalikan nama akun saya.


Pengujian

Juga, jika Anda ingin membandingkan sendiri opsi-opsi ini, berikut adalah skrip yang dapat Anda gunakan untuk menjalankan skrip sebagai pengguna lain. Anda perlu menggunakan cmdlet Get-Credential untuk mendapatkan objek kredensial, dan kemudian jalankan skrip ini dengan skrip untuk dijalankan sebagai pengguna lain sebagai argumen 1, dan objek kredensial sebagai argumen 2.

Pemakaian:

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

Isi skrip 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
sumber
Untuk PowerShell 6 di Mac OS X dan Linux, [Environment]::UserNameadalah pilihan terbaik, karena berfungsi lintas platform. whoamitampaknya juga berfungsi, tetapi tergantung pada whoamialat yang tersedia di platform.
Florian Feldhaus
Untuk Powershell 6 di Windows, $env:USERNAMEhasilkan SYSTEMkecuali saya menjalankan sebagai administrator, sementara [Environment]::UserName]menghasilkan nama pengguna saya.
kfsone
1
Sepertinya Get-WmiObjectmetode ini tidak lagi berfungsi di pwsh. Bahkan mencoba mengimpor modul kompatibilitas dan Microsoft.PowerShell.Managementyang memiliki cmdlet. Adakah yang tahu apa yang terjadi?
not2qubit
Benar. Hal itu terganggu selama Mendapatkan-CimInstance cukup waktu lalu untuk alasan kinerja ... dan CIM memiliki untuk digunakan di atas WMI di v6 untuk alasan kompatibilitas silang. Jika Anda melihat perintah dengan GWMI, periksa apakah Anda dapat melakukan GCIM sebagai gantinya.
Hicsy
105

$env:username adalah cara termudah

Eoin
sumber
Anda dapat menetapkannya dengan cara ini, dan membangun direktori dan yang tidak.
Droogans
51

Saya ingin memasukkan perintah whoami , yang pada dasarnya adalah alias yang bagus untuk melakukan %USERDOMAIN%\%USERNAME%seperti yang diusulkan dalam jawaban lain.

Write-Host "current user:"
Write-Host $(whoami)
galaktor
sumber
itu bekerja untuk saya di PS versi 2. Apakah Anda mengatakan itu dijatuhkan di PS3? C: \> powershell Windows PowerShell Hak Cipta (C) 2009 Microsoft Corporation. Seluruh hak cipta. PS C: \> whoami mydomain \ myusername
galaktor
2
$env:USERNAMEdapat diubah oleh pengguna, tetapi ini tidak akan dibodohi dengan melakukan itu.
Kevin Panko
3
whoami menang untuk penggunaan interaktif. Cukup singkat sehingga saya bisa mengingat bagaimana mengetiknya tanpa berkonsultasi SO :-)
Iain Samuel McLean Elder
Bukan hal di Server Nano. Jangan menggunakannya dalam skrip, lakukan hal yang benar ( [System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
Yet Another User
whoamiadalah executable. Itu tidak dapat dihapus dari PowerShell. Ini berpotensi dihapus dari Windows, tetapi masih ada pada Windows Server non-Nano 2012.
jpmc26
37

[Environment]::UserNamemengembalikan hanya nama pengguna. Misalnya bob [System.Security.Principal.WindowsIdentity]::GetCurrent().Name mengembalikan nama pengguna, diawali dengan domainnya jika sesuai. Misalnya SOMEWHERENICE \ bob

WaffleSouffle
sumber
12

Saya telah menggunakan $env:usernamedi masa lalu, tetapi seorang rekan menunjukkan itu adalah variabel lingkungan dan dapat diubah oleh pengguna dan oleh karena itu, jika Anda benar-benar ingin mendapatkan nama pengguna pengguna saat ini, Anda tidak boleh mempercayainya.

Saya akan mendukung jawaban Mark Seemann: [System.Security.Principal.WindowsIdentity] :: GetCurrent (). Name

Tapi saya tidak diizinkan. Dengan jawaban Mark, jika Anda hanya perlu nama pengguna, Anda mungkin harus menguraikannya sejak di sistem saya, itu kembali hostname\usernamedan pada mesin yang bergabung dengan domain dengan akun domain itu akan kembali domain\username.

Saya tidak akan menggunakan whoami.exekarena tidak ada di semua versi Windows, dan itu panggilan ke biner lain dan mungkin memberikan beberapa tim keamanan cocok.

Dave Hull
sumber
1
Karena OP memang bertanya tentang Windows-Powershell, itu valid, tetapi [Environment]::UserNamekurang mengetik, independen $env:usernamedan lintas-platform: Lihat pastebin.com/GsfR6Hrp
kfsone
12

Sekarang PowerShell Core (alias v6) telah dirilis, dan orang mungkin ingin menulis skrip lintas-platform, banyak jawaban di sini tidak akan berfungsi selain Windows.

[Environment]::UserName tampaknya menjadi cara terbaik untuk mendapatkan nama pengguna saat ini di semua platform yang didukung oleh PowerShell Core jika Anda tidak ingin menambahkan deteksi platform dan casing khusus ke kode Anda.

Edouard Poor
sumber
10

Hanya membangun karya orang lain di sini:

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

$username

Nama pengguna kedua adalah hanya untuk tujuan tampilan jika Anda menyalin dan menempelnya.

clayton.nichols
sumber
$ fullname = Get-WMIObject -class Win32_ComputerSystem | Select-Object -ExpandProperty username $ username = $ fullname.Replace ("DOMAIN \", "") $ username
clayton.nichols
-1

Saya tidak melihat contoh berbasis Add-Type . Ini adalah salah satu yang menggunakan GetUserName langsung dari 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
sumber
1
Tolong jelaskan apa yang dilakukan kode ini dan mengapa ini akan lebih bermanfaat daripada salah satu metode yang lebih pendek.
Benjamin Hubbard
@BenjaminHubbard Pertanyaannya tidak menanyakan metode terpendek, tetapi menanyakan cara menyelesaikan prestasi dengan PowerShell. Ini melakukan trik berbeda dari contoh-contoh lain dengan memanggil fungsi di dalam dll dan menggunakan metode Add-Type untuk mengakses .NET.
Knuckle-Dragger
1
Meskipun ini adalah blok kode novel, akan lebih bagus jika saya tahu apa yang sedang dilakukannya. Bisakah Anda membubuhi keterangan dengan komentar, mungkin? Terima kasih!
jpaugh
1
Saya hampir ingin meneguhkan hati, karena saya melihat pantasnya proposal. Namun kode tersebut memiliki beberapa kelemahan: kode ini memperkenalkan namespace baru, menggunakan konstanta ajaib (64) yang nilainya tidak seperti yang diresepkan dokter (seharusnya UNLEN+1, dan UNLEN256), ia mengabaikan kesalahan yang mungkin dikembalikan dari GetUserName (melalui ia mempertahankan GetLastError, poin yang bagus), ia tidak membersihkan buffer string; dan mungkin beberapa yang lain. Dan seperti yang orang lain katakan, komentar juga sangat hilang.
AntoineL
-1

Saya menemukan yang paling mudah digunakan: cd $ home \ Desktop \

akan membawa Anda ke desktop pengguna saat ini

Dalam kasus saya, saya perlu mengambil nama pengguna untuk mengaktifkan skrip untuk mengubah jalur, yaitu. c: \ users \% username%. Saya perlu memulai skrip dengan mengubah path ke desktop pengguna. Saya dapat melakukan ini, dengan bantuan dari atas dan dari tempat lain, dengan menggunakan applet get-location.

Anda mungkin memiliki cara lain, atau bahkan lebih baik untuk melakukannya, tetapi ini berhasil bagi saya:

$ Path = Dapatkan-Lokasi

Set-Lokasi $ Path \ Desktop

Kes tas
sumber
Membuat asumsi apa pun berdasarkan direktori home terikat hanya berfungsi di bawah kondisi yang sangat spesifik.
Raúl Salinas-Monteagudo
Jika Anda bekerja di terminal PowerShell dan hanya dengan cepat ingin mengetahui pengguna apa Anda, maka mengetik "ls ~" harus melakukan trik. Seperti poster di atas, mungkin ada pengecualian, dan ini jelas tidak baik untuk skrip, jadi gunakan contoh Edouard Poor dalam kasus itu.
MrBerta
-2

Jika sudah terbiasa, Anda dapat menelepon

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

Ini pada dasarnya mencuri output dari apa yang akan Anda dapatkan jika Anda memiliki file batch hanya dengan "echo% username%".

shaw
sumber
1
Saya downvoting karena: a) Anda $(...)itu berlebihan: $a = cmd.exe /c echo %username%bekerja, b) itu tidak portabel, c) itu tidak benar-benar menjawab pertanyaan tentang bagaimana melakukannya dalam PowerShell, ia menjawab bagaimana melakukannya dalam dos, dan itu lebih baik memberi seorang pria pancing daripada memberinya ikan, misalnya 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
sumber
$ content = get-content "cm.txt" ---- $ count = 0 ----- foreach ($ line dalam $ count) ---- {$ count = $ count + 1} ---- tulis -Hosting "Anda memiliki banyak baris ini:" $ count
ammy
1. $ a = $ com1, $ com2 ------ write-host "masukkan cm name" ---- $ c = readhost ----- write-host $ a [$ c-1] .username , tulis-host $ a [$ c-1] .password
ammy
$ com1 = objek-baru PSobject ----- $ com1 = $ com1 | add-member noteproperty -name username -value 2016
ammy
1
adakah alasan mengapa Anda menambahkan kode sebagai komentar atas jawaban Anda sendiri?
aldr
1
mengapa Anda tidak mengedit jawaban Anda dan menambahkan kode alih-alih membaginya dalam komentar seperti itu di mana tidak ada yang akan memahaminya?
aldr
-4

Dalam kasus saya, saya perlu mengambil nama pengguna untuk mengaktifkan skrip untuk mengubah jalur, yaitu. c:\users\%username%\. Saya perlu memulai skrip dengan mengubah path ke desktop pengguna. Saya dapat melakukan ini, dengan bantuan dari atas dan dari tempat lain, dengan menggunakan applet get-location .

Anda mungkin memiliki cara lain, atau bahkan lebih baik untuk melakukannya, tetapi ini berhasil bagi saya:

$Path = Get-Location

Set-Location $Path\Desktop
kjp
sumber
1
Selamat Datang di Stack Overflow ! Ini setara dengan Set-Location Desktop. ( Get-Locationhanya mengembalikan lokasi saat ini, yang tersirat untuk Set-Locationdengan jalur relatif.)
jpaugh