Làm cách nào để có được tên người dùng hiện tại trong Windows PowerShell?


Câu trả lời:


398

Tôi đã tìm thấy nó:

$env:UserName

Ngoài ra còn có:

$env:UserDomain
$env:ComputerName

10
Một cách khác nhanh chóng và bẩn thỉu là $env:usernamelấy tên người dùng từ biến môi trường tương ứng.
guillermooo

7
Tôi nghĩ $ env: tên người dùng và [Môi trường] :: Tên người dùng đều trỏ đến cùng một thứ.
Cephas

16
Cảm ơn đã trở lại để trả lời câu hỏi của riêng bạn. Không có gì bực bội hơn khi ai đó tự tìm ra câu trả lời và chỉ đơn giản trả lời: "Đừng bận tâm, hiểu rồi!"
Matt DiTrolio

6
@MattDiTrolio Điều đó chắc chắn là bực bội, nhưng bạn nghĩ không có bực bội hơn thế?!
Code

5
@CodeJ Racer Không có gì. Không trong lịch sử bao giờ. :)
Matt DiTrolio

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

16
Đây là câu trả lời an toàn nhất vì người dùng $env:USERNAMEcó thể thay đổi, nhưng điều này sẽ không bị đánh lừa khi làm điều đó.
Kevin Panko

6
@KevinPanko Đúng, nhưng tại thời điểm mà bạn không thể tin tưởng người dùng của mình, có những câu hỏi khác, mang tính triết học hơn cần được hỏi. ;-)
jpaugh

4
Phương pháp này bao gồm tên miền và tên người dùng. Chắc chắn có lợi nếu bạn có nhiều tên miền đang chơi.
Ryan Gates

Hoạt động như mong đợi. Đã kiểm tra để đặt địa chỉ url.
Marek Bar

Ngoài ra, điều này cũng có vẻ hoạt động trong PowerShell 6, có nghĩa là nó tương thích với nhiều nền tảng (.Net Standard). Nghĩ rằng nó đáng được đề cập kể từ khi tôi đặt câu hỏi khi tôi thấy không gian tên.
deadlydog

120

Tôi nghĩ rằng nó sẽ có giá trị để tóm tắt và so sánh các câu trả lời đã cho.

Nếu bạn muốn truy cập biến môi trường :

(tùy chọn dễ dàng hơn / ngắn hơn / dễ nhớ)

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

Nếu bạn muốn truy cập mã thông báo truy cập Windows :

(tùy chọn đáng tin cậy hơn)

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

Nếu bạn muốn tên của người dùng đã đăng nhập

(thay vì tên của người dùng đang chạy phiên bản PowerShell)


So sánh

Nhận xét của @Kevin Panko về câu trả lời của @Mark Seemann với việc chọn một trong các danh mục khác:

[Cách tiếp cận mã thông báo truy cập Windows] là câu trả lời an toàn nhất, bởi vì $ env: USERNAME có thể bị thay đổi bởi người dùng, nhưng điều này sẽ không bị đánh lừa khi làm điều đó.

Nói tóm lại, tùy chọn biến môi trường ngắn gọn hơn và tùy chọn mã thông báo truy cập Windows đáng tin cậy hơn.

Tôi đã phải sử dụng phương pháp tiếp cận mã thông báo truy cập Windows của @Mark Seemann trong tập lệnh PowerShell mà tôi đang chạy từ ứng dụng C # với mạo danh.

Ứng dụng C # được chạy với tài khoản người dùng của tôi và nó chạy tập lệnh PowerShell dưới dạng tài khoản dịch vụ. Do hạn chế về cách tôi chạy tập lệnh PowerShell từ C #, phiên bản PowerShell sử dụng các biến môi trường của tài khoản người dùng của tôi, mặc dù nó được chạy với tư cách là người dùng tài khoản dịch vụ.

Trong thiết lập này, các tùy chọn biến môi trường trả về tên tài khoản của tôi và tùy chọn mã thông báo truy cập Windows trả về tên tài khoản dịch vụ (đó là những gì tôi muốn) và tùy chọn người dùng đã đăng nhập trả về tên tài khoản của tôi.


Kiểm tra

Ngoài ra, nếu bạn muốn tự so sánh các tùy chọn, đây là tập lệnh bạn có thể sử dụng để chạy tập lệnh với tư cách người dùng khác. Bạn cần sử dụng lệnh ghép ngắn Get-Credential để lấy đối tượng thông tin xác thực, sau đó chạy tập lệnh này với tập lệnh để chạy như một người dùng khác làm đối số 1 và đối tượng thông tin làm đối số 2.

Sử dụng:

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

Nội dung của tập lệnh 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"

Đối với PowerShell 6 trên Mac OS X và Linux, [Environment]::UserNamelà tùy chọn tốt nhất, vì nó hoạt động đa nền tảng. whoamidường như cũng hoạt động, nhưng phụ thuộc vào whoamicông cụ có sẵn trên nền tảng.
Florian Feldhaus

Đối với Powershell 6 trên Windows, hãy $env:USERNAMEtạo ra SYSTEMtrừ khi tôi chạy với tư cách quản trị viên, trong khi vẫn [Environment]::UserName]mang lại tên người dùng của mình.
kfsone

1
Có vẻ như Get-WmiObjectphương pháp không còn hoạt động trong pwsh. Thậm chí đã cố gắng nhập mô-đun tương thích và cái Microsoft.PowerShell.Managementđó có lệnh ghép ngắn. Bất cứ ý tưởng những gì đang xảy ra?
not2qubit

Chính xác. Nó được lúng túng hơn để Get-CimInstance khá một thời gian trở lại vì lý do hiệu suất ... và CIM được sử dụng trên WMI trong v6 vì lý do cross-tương thích. Nếu bạn thấy một lệnh với GWMI, hãy kiểm tra xem bạn có thể thực hiện GCIM không.
Hicsy

105

$env:username là cách dễ nhất


Bạn có thể chỉ định nó theo cách này, và xây dựng các thư mục và những gì không.
Dropogans

51

Tôi muốn đưa ra lệnh whoami , về cơ bản là một bí danh hay để thực hiện %USERDOMAIN%\%USERNAME%như đề xuất trong các câu trả lời khác.

Write-Host "current user:"
Write-Host $(whoami)

nó hoạt động với tôi trên phiên bản PS 2. Bạn có nói rằng nó đã bị rớt trong PS3 không? C: \> powershell Windows PowerShell Bản quyền (C) 2009 Tập đoàn Microsoft. Đã đăng ký Bản quyền. PS C: \> whoami mydomain \ myusername
galaktor

2
$env:USERNAMEngười dùng có thể thay đổi, nhưng điều này sẽ không bị đánh lừa khi làm điều đó.
Kevin Panko

3
Whoami thắng để sử dụng tương tác. Nó đủ ngắn để tôi có thể nhớ cách gõ mà không cần tham khảo SO :-)
Iain Samuel McLean Elder

Không phải là một điều trong Nano Server. Đừng sử dụng nó trong các tập lệnh, hãy làm điều đúng ( [System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
Tuy nhiên, một người dùng khác

whoamilà một thực thi. Nó không thể bị xóa khỏi PowerShell. Nó có khả năng có thể bị xóa khỏi Windows, nhưng nó vẫn ở đó kể từ máy chủ Windows không phải là Nano 2012.
jpmc26

37

[Environment]::UserNamechỉ trả về tên người dùng. Ví dụ: bob [System.Security.Principal.WindowsIdentity]::GetCurrent().Name trả về tên người dùng, được đặt trước bởi tên miền của nó khi thích hợp. Ví dụ: SOMEWHERENICE \ bob


12

Tôi đã sử dụng $env:usernametrước đây, nhưng một đồng nghiệp đã chỉ ra đó là biến môi trường và người dùng có thể thay đổi và do đó, nếu bạn thực sự muốn lấy tên người dùng hiện tại, bạn không nên tin vào nó.

Tôi muốn nâng cao câu trả lời của Mark Seemann: [System.Security.Principal.WindowsIdentity] :: GetCản (). Tên

Nhưng tôi không được phép. Với câu trả lời của Mark, nếu bạn chỉ cần tên người dùng, bạn có thể phải phân tích nó vì trên hệ thống của tôi, nó sẽ trả về hostname\usernamevà trên các máy được nối với tên miền có tài khoản miền thì nó sẽ trả về domain\username.

Tôi sẽ không sử dụng whoami.exevì nó không có trên tất cả các phiên bản Windows và nó được gọi là một nhị phân khác và có thể cung cấp cho một số nhóm bảo mật phù hợp.


1
Vì OP đã hỏi về Windows-Powershell, điều đó hợp lệ, nhưng [Environment]::UserNameít gõ, độc lập $env:usernamevà đa nền tảng: Xem pastebin.com/GsfR6Hrp
kfsone

12

Bây giờ PowerShell Core (còn gọi là v6) đã được phát hành và mọi người có thể muốn viết các tập lệnh đa nền tảng, nhiều câu trả lời ở đây sẽ không hoạt động trên bất kỳ thứ gì ngoài Windows.

[Environment]::UserName dường như là cách tốt nhất để có được tên người dùng hiện tại trên tất cả các nền tảng được PowerShell Core hỗ trợ nếu bạn không muốn thêm phát hiện nền tảng và vỏ đặc biệt vào mã của mình.


10

Chỉ cần xây dựng dựa trên công việc của người khác ở đây:

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

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

$username

Các thứ hai tên là để trưng bày chỉ nhằm mục đích duy nhất nếu bạn sao chép và dán nó.


$ fullname = Get-WMIObject-class Win32_ComputerSystem | Chọn-Object -ExpandProperty tên người dùng $ username = $ fullname.Replace ("DOMAIN \", "") $ tên người dùng
clayton.nichols

-1

Tôi không thấy bất kỳ ví dụ dựa trên Add-Type nào . Đây là một cách sử dụng GetUserName trực tiếp từ 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()

1
Vui lòng giải thích những gì mã này đang làm và tại sao nó sẽ hữu ích hơn một trong những phương thức ngắn hơn.
Benjamin Hubbard

@BenjaminHubbard Câu hỏi không yêu cầu phương pháp ngắn nhất, nó hỏi làm thế nào để hoàn thành kỳ tích với powershell. Điều này thực hiện thủ thuật khác với các ví dụ khác bằng cách gọi hàm bên trong dll và sử dụng phương thức Add-Type để truy cập .NET.
Knuckle-Dragger 24/07/2015

1
Mặc dù đây là một khối mã mới lạ, nhưng thật tuyệt nếu tôi biết nó đang làm cái quái gì. Bạn có thể chú thích nó với ý kiến, có thể? Cảm ơn!
jpaugh

1
Tôi gần như muốn upvote, vì tôi thấy công đức cho đề xuất này. Tuy nhiên, mã có một số sai sót: nó giới thiệu một không gian tên mới, nó sử dụng hằng số ma thuật (64), giá trị không phải là thứ mà bác sĩ đã chỉ định (nên là UNLEN+1, và UNLENlà 256), nó bỏ qua mọi lỗi có thể được trả về từ GetUserName (thông qua nó bảo tồn GetLastError, một điểm tốt), nó không dọn sạch bộ đệm chuỗi; và có lẽ một số người khác. Và như những người khác nói, bình luận cũng vô cùng thiếu.
AntoineL

-1

Tôi thấy dễ sử dụng nhất: cd $ home \ Desktop \

sẽ đưa bạn đến màn hình người dùng hiện tại

Trong trường hợp của tôi, tôi cần phải lấy tên người dùng để cho phép tập lệnh thay đổi đường dẫn, tức là. c: \ người dùng \% tên người dùng%. Tôi cần bắt đầu tập lệnh bằng cách thay đổi đường dẫn đến màn hình của người dùng. Tôi đã có thể làm điều này, với sự giúp đỡ từ phía trên và những nơi khác, bằng cách sử dụng applet vị trí get.

Bạn có thể có một cách khác, hoặc thậm chí tốt hơn để làm điều đó, nhưng điều này làm việc cho tôi:

$ Path = Nhận vị trí

Đặt vị trí $ Path \ Desktop


Thực hiện bất kỳ giả định nào dựa trên thư mục chính bị ràng buộc chỉ hoạt động trong các điều kiện rất cụ thể.
Raúl Salinas-Monteagudo

Nếu bạn đang làm việc trong một thiết bị đầu cuối powershell và chỉ muốn nhanh chóng tìm hiểu xem bạn là người dùng nào, thì gõ "ls ~" nên thực hiện thủ thuật. Giống như poster ở trên, có thể có ngoại lệ và điều này chắc chắn không tốt cho các kịch bản, vì vậy hãy sử dụng ví dụ của Edouard Poor trong trường hợp đó.
MrBerta

-2

Nếu bạn đã quen với lô, bạn có thể gọi

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

Điều này về cơ bản đánh cắp đầu ra từ những gì bạn sẽ nhận được nếu bạn có một tệp bó chỉ với "echo% username%".


1
Tôi đang từ chối vì: a) Bạn $(...)là người thừa thãi: $a = cmd.exe /c echo %username%hoạt động, b) nó không phải là di động, c) nó không thực sự trả lời câu hỏi làm thế nào để làm điều đó trong powershell, nó trả lời làm thế nào để làm điều đó trong dos, và nó tốt hơn là cho một người đàn ông một cái cần câu hơn là cho anh ta một con cá, ví dụ 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}

$ nội dung = get-content "cm.txt" ---- $ Count = 0 ----- foreach ($ line in $ Count) ---- {$ Count = $ Count + 1} ---- write -host "bạn có nhiều dòng này:" $ Count
ammy

1. $ a = $ com1, $ com2 ------ write-host "nhập tên cm" ---- $ c = readhost ----- write-host $ a [$ c-1] .username , ghi-host $ a [$ c-1] .password
Ammy

$ com1 = PSobject đối tượng mới ----- $ com1 = $ com1 | add-thành viên noteproperty -name username -value 2016
ammy

1
Có một lý do tại sao bạn thêm mã dưới dạng nhận xét về câu trả lời của riêng bạn?
aldr

1
Tại sao bạn không chỉnh sửa câu trả lời của mình và thêm mã thay vì chia nó ra trong các bình luận như thế mà không ai sẽ hiểu nó?
aldr

-4

Trong trường hợp của tôi, tôi cần phải lấy tên người dùng để cho phép tập lệnh thay đổi đường dẫn, tức là. c:\users\%username%\. Tôi cần bắt đầu tập lệnh bằng cách thay đổi đường dẫn đến màn hình của người dùng. Tôi đã có thể làm điều này, với sự giúp đỡ từ phía trên và những nơi khác, bằng cách sử dụng applet vị trí get .

Bạn có thể có một cách khác, hoặc thậm chí tốt hơn để làm điều đó, nhưng điều này làm việc cho tôi:

$Path = Get-Location

Set-Location $Path\Desktop

1
Chào mừng bạn đến với Stack Overflow ! Điều này tương đương với Set-Location Desktop. ( Get-Locationchỉ trả về vị trí hiện tại, ẩn Set-Locationvới đường dẫn tương đối.)
jpaugh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.