ฉันจะรับชื่อผู้ใช้ปัจจุบันใน Windows PowerShell ได้อย่างไร


คำตอบ:


397

เจอแล้ว:

$env:UserName

นอกจากนี้ยังมี:

$env:UserDomain
$env:ComputerName

10
ทางเลือกที่รวดเร็วและสกปรกคือ$env:usernameการดึงชื่อผู้ใช้จากตัวแปรสภาพแวดล้อมที่สอดคล้องกัน
guillermooo

7
ฉันคิดว่า $ env: ชื่อผู้ใช้และ [สิ่งแวดล้อม] :: ชื่อผู้ใช้ชี้ไปที่สิ่งเดียวกัน
Cephas

16
ขอบคุณที่กลับมาตอบคำถามของคุณเอง ไม่มีอะไรน่าผิดหวังเมื่อมีคนคิดคำตอบและตอบกลับว่า "ไม่เป็นไรเข้าใจเลย!"
Matt DiTrolio

6
@MattDiTrolio แน่นอนว่ามันน่าหงุดหงิด แต่คุณคิดว่าไม่มีอะไรน่าผิดหวังไปกว่านี้อีกแล้ว!
รหัส Jockey

5
@ CodeJockey ไม่มีอะไร ไม่ได้อยู่ในประวัติศาสตร์เลยทีเดียว :)
Matt DiTrolio

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

16
นี่เป็นคำตอบที่ปลอดภัยที่สุดเพราะผู้ใช้$env:USERNAMEสามารถเปลี่ยนแปลงได้ แต่จะไม่ถูกหลอกโดยการทำเช่นนั้น
Kevin Panko

6
@KevinPanko True แต่ ณ จุดที่คุณไม่สามารถเชื่อถือผู้ใช้ของคุณมีคำถามอื่น ๆ อีกมากมายที่ต้องถามทางปรัชญา ;-)
jpaugh

4
วิธีนี้รวมถึงชื่อโดเมนและชื่อผู้ใช้ ประโยชน์แน่นอนถ้าคุณมีหลายโดเมนในการเล่น
Ryan Gates

ทำงานได้ตามที่คาดหวัง ผ่านการทดสอบสำหรับการจองที่อยู่ URL
Marek Bar

นอกจากนี้ดูเหมือนว่าจะทำงานใน 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 จะส่งคืนชื่อบัญชีบริการ (ซึ่งเป็นสิ่งที่ฉันต้องการ) และตัวเลือกผู้ใช้ที่ล็อกอินจะคืนชื่อบัญชีของฉัน


การทดสอบ

นอกจากนี้หากคุณต้องการเปรียบเทียบตัวเลือกด้วยตัวคุณเองนี่คือสคริปต์ที่คุณสามารถใช้เพื่อเรียกใช้สคริปต์ในฐานะผู้ใช้รายอื่น คุณจำเป็นต้องใช้ cmdlet รับข้อมูลประจำตัวเพื่อรับวัตถุข้อมูลประจำตัวแล้วเรียกใช้สคริปต์นี้ด้วยสคริปต์เพื่อเรียกใช้ในฐานะผู้ใช้อื่นเป็นอาร์กิวเมนต์ 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"

สำหรับ PowerShell 6 บน Mac OS X และ Linux [Environment]::UserNameเป็นตัวเลือกที่ดีที่สุดเนื่องจากทำงานข้ามแพลตฟอร์มได้ whoamiดูเหมือนว่าจะใช้งานได้ แต่ขึ้นอยู่กับwhoamiเครื่องมือที่มีอยู่บนแพลตฟอร์ม
Florian Feldhaus

สำหรับ Powershell 6 บน Windows $env:USERNAMEให้สร้างSYSTEMเว้นแต่ว่าฉันจะเป็นผู้ดูแลระบบในขณะที่[Environment]::UserName]ให้ชื่อผู้ใช้ของฉันด้วยวิธีใดก็ตาม
kfsone

1
ดูเหมือนว่าGet-WmiObjectวิธีการไม่ทำงานใน pwsh อีกต่อไป แม้จะพยายามนำเข้าโมดูลความเข้ากันได้และMicrosoft.PowerShell.Managementที่มี cmdlet ความคิดใด ๆ ที่เกิดขึ้น?
not2qubit

แก้ไข. Get-CimInstance กลับมาอีกซักพักด้วยเหตุผลด้านประสิทธิภาพ ... และ CIMได้ถูกนำมาใช้ในช่วง WMI ใน v6 สำหรับเหตุผลที่ข้ามเข้ากันได้ หากคุณเห็นคำสั่งด้วย GWMI ให้ตรวจสอบว่าคุณสามารถทำ GCIM แทนได้หรือไม่
Hicsy

105

$env:username เป็นวิธีที่ง่ายที่สุด


คุณสามารถกำหนดด้วยวิธีนี้และสร้างไดเรกทอรีและสิ่งที่ไม่
Droogans

51

ฉันต้องการที่จะโยนคำสั่งwhoamiซึ่งโดยทั่วไปเป็นนามแฝงที่ดีสำหรับการทำ%USERDOMAIN%\%USERNAME%ตามที่เสนอในคำตอบอื่น ๆ

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

มันทำงานได้ดีสำหรับฉันในรุ่น PS 2 คุณบอกว่ามันถูกทิ้งใน PS3? C: \> PowerShell ลิขสิทธิ์ Windows PowerShell (C) 2009 Microsoft Corporation สงวนลิขสิทธิ์. PS C: \> whoami mydomain \ myusername
galaktor

2
$env:USERNAMEผู้ใช้สามารถเปลี่ยนแปลงได้ แต่สิ่งนี้จะไม่ถูกหลอกโดยการทำเช่นนั้น
Kevin Panko

3
whoami ชนะการใช้แบบโต้ตอบ มันสั้นพอที่ฉันจะจำวิธีพิมพ์ได้โดยไม่ต้องปรึกษา SO :-)
Iain Samuel McLean Elder

ไม่ใช่สิ่งที่อยู่ในเซิร์ฟเวอร์นาโน อย่าใช้มันในสคริปต์ทำสิ่งที่ถูกต้อง ( [System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
ผู้ใช้คนอื่น

whoamiเป็นปฏิบัติการ ไม่สามารถลบได้จาก PowerShell มันอาจถูกลบออกจาก Windows แต่ก็ยังคงเป็นของ Windows Server 2012 ไม่ใช่นาโน
jpmc26

37

[Environment]::UserNameส่งคืนเฉพาะชื่อผู้ใช้ เช่นbob [System.Security.Principal.WindowsIdentity]::GetCurrent().Nameส่งคืนชื่อผู้ใช้นำหน้าด้วยโดเมนตามความเหมาะสม เช่นSOMEWHERENICE \ bob


12

ฉันได้ใช้ $env:usernameมาก่อน แต่มีเพื่อนร่วมงานชี้ให้เห็นว่ามันเป็นตัวแปรสภาพแวดล้อมและผู้ใช้สามารถเปลี่ยนแปลงได้ดังนั้นหากคุณต้องการได้รับชื่อผู้ใช้ปัจจุบันคุณไม่ควรเชื่อถือ

ฉันขอคำตอบของ Mark Seemann: [System.Security.Principal.WindowsIdentity] :: GetCurrent ()

แต่ฉันไม่ได้รับอนุญาต กับคำตอบมาร์คถ้าคุณต้องการเพียงชื่อผู้ใช้ที่คุณอาจจะต้องแยกมันออกมาตั้งแต่ในระบบของฉันก็จะส่งกลับและในโดเมนเครื่องร่วมกับบัญชีโดเมนก็จะกลับhostname\usernamedomain\username

ฉันจะไม่ใช้whoami.exeเนื่องจากไม่มีใน Windows ทุกรุ่นและเป็นการเรียกเลขฐานสองอื่นและอาจให้ทีมรักษาความปลอดภัยบางส่วนเข้ากันได้


1
เนื่องจาก OP ได้ถามเกี่ยวกับ Windows-Powershell ว่าถูกต้อง แต่[Environment]::UserNameมีการพิมพ์น้อยกว่าไม่ขึ้นกับ$env:usernameและข้ามแพลตฟอร์ม: ดูpastebin.com/GsfR6Hrp
kfsone

12

ตอนนี้PowerShell Core (aka v6) เปิดตัวแล้วและผู้คนอาจต้องการเขียนสคริปต์ข้ามแพลตฟอร์มคำตอบมากมายที่นี่จะไม่ทำงานกับสิ่งอื่นนอกจาก Windows

[Environment]::UserName ดูเหมือนจะเป็นวิธีที่ดีที่สุดในการรับชื่อผู้ใช้ปัจจุบันในทุกแพลตฟอร์มที่ได้รับการสนับสนุนโดย PowerShell Core หากคุณไม่ต้องการเพิ่มการตรวจจับแพลตฟอร์มและปลอกพิเศษในรหัสของคุณ


10

เพียงสร้างผลงานของผู้อื่นที่นี่:

[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

สอง ชื่อผู้ใช้สำหรับการแสดงผลเท่านั้นถ้าคุณคัดลอกและวาง


$ fullname = Get-WMIObject -class Win32_ComputerSystem | เลือก - วัตถุ - ขยายคุณสมบัติชื่อผู้ใช้ $ ชื่อผู้ใช้ = $ ชื่อเต็มแทนที่ "DOMAIN \", "") $ ชื่อผู้ใช้
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()

1
โปรดอธิบายว่ารหัสนี้ทำอะไรและทำไมจึงมีประโยชน์มากกว่าหนึ่งในวิธีที่สั้นกว่านี้
Benjamin Hubbard

@BenjaminHubbard คำถามไม่ขอวิธีที่สั้นที่สุดก็ถามว่าจะบรรลุความสำเร็จด้วย powershell นี่เป็นการหลอกลวงต่างจากตัวอย่างอื่นโดยการเรียกใช้ฟังก์ชันภายใน dll และใช้เมธอด Add-Type เพื่อเข้าถึง. NET
Knuckle-Dragger

1
ในขณะที่นี่เป็นบล็อกรหัสนวนิยายจะดีถ้าฉันรู้ว่า heck มันกำลังทำอะไร คุณสามารถอธิบายด้วยความคิดเห็นได้ไหม? ขอบคุณ!
jpaugh

1
ฉันเกือบอยากจะถอนรากถอนโคนเนื่องจากเห็นข้อเสนอ แต่รหัสมีข้อบกพร่องบางอย่าง: มันแนะนำเนมสเปซใหม่มันใช้ค่าคงที่เวทย์มนตร์ (64) ซึ่งค่าไม่ใช่สิ่งที่แพทย์กำหนด (ควรเป็นUNLEN+1และUNLEN256) มันไม่สนใจข้อผิดพลาดใด ๆ ซึ่งอาจส่งคืนจาก GetUserName (ผ่าน มันรักษา GetLastError เป็นจุดที่ดี) มันไม่ได้ทำความสะอาดบัฟเฟอร์สตริง; และอาจอื่น ๆ และอย่างที่คนอื่นพูดความเห็นก็หายไปอย่างมากเช่นกัน
AntoineL

-1

ฉันพบว่าใช้งานง่ายที่สุด: cd $ home \ Desktop \

จะนำคุณไปยังเดสก์ท็อปผู้ใช้ปัจจุบัน

ในกรณีของฉันฉันต้องดึงชื่อผู้ใช้เพื่อเปิดใช้งานสคริปต์เพื่อเปลี่ยนเส้นทางเช่น C: \ Users \% username% ฉันต้องการเริ่มสคริปต์โดยเปลี่ยนเส้นทางไปยังเดสก์ท็อปผู้ใช้ ฉันสามารถทำได้ด้วยความช่วยเหลือจากด้านบนและที่อื่น ๆ โดยใช้แอปเพล็ต get-location

คุณอาจมีวิธีอื่นหรือดีกว่าที่จะทำ แต่วิธีนี้ใช้ได้ผลสำหรับฉัน:

$ Path = ตำแหน่งที่รับ

กำหนดตำแหน่ง $ Path \ Desktop


การตั้งสมมติฐานใด ๆ โดยยึดตามโฮมไดเร็กตอรี่จะทำงานภายใต้เงื่อนไขที่เฉพาะเจาะจงเท่านั้น
Raúl Salinas-Monteagudo

หากคุณกำลังทำงานในสถานี powershell และเพียงแค่ต้องการค้นหาอย่างรวดเร็วว่าคุณเป็นผู้ใช้จากนั้นพิมพ์ "ls ~" ควรทำเคล็ดลับ เช่นเดียวกับโปสเตอร์ด้านบนอาจมีข้อยกเว้นและนี่ไม่เหมาะกับสคริปต์ดังนั้นให้ใช้ตัวอย่างของ Edouard Poor ในกรณีนั้น
MrBerta

-2

หากคุณคุ้นเคยกับชุดคุณสามารถโทร

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

สิ่งนี้จะขโมยเอาท์พุทจากสิ่งที่คุณจะได้รับหากคุณมีไฟล์แบตช์ที่มีเพียง "echo% ชื่อผู้ใช้%"


1
ฉันกำลัง downvoting เพราะ: a) คุณ$(...)เป็นคนที่ฟุ่มเฟือย: $a = cmd.exe /c echo %username%ทำงาน, b) มันไม่ได้พกพาได้, c) มันไม่ได้ตอบคำถามว่าจะทำอย่างไรใน 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}

$ content = get-content "cm.txt" ---- $ count = 0 ----- foreach ($ line in $ count) ---- {$ count = $ count + 1} ---- เขียน - โฮสต์ "คุณมีหลายบรรทัด:" $ count
ammy

1. $ a = $ com1, $ com2 ------ เขียนโฮสต์ "ป้อนชื่อซม." ---- $ c = readhost ----- เขียนโฮสต์ $ a [$ c-1] .username เขียนโฮสต์ $ a [$ c-1] .password
ammy

$ com1 = วัตถุใหม่ PSobject ----- $ com1 = $ com1 | เพิ่มสมาชิก noteproperty - ชื่อผู้ใช้ -value 2016
ammy

1
มีเหตุผลทำไมคุณเพิ่มรหัสเป็นความคิดเห็นในคำตอบของคุณเอง?
aldr

1
ทำไมคุณไม่แก้ไขคำตอบของคุณและเพิ่มรหัสแทนที่จะแยกมันออกเป็นความคิดเห็นแบบที่ไม่มีใครจะเข้าใจได้?
aldr

-4

ในกรณีของฉันฉันต้องดึงชื่อผู้ใช้เพื่อเปิดใช้งานสคริปต์เพื่อเปลี่ยนเส้นทางเช่น c:\users\%username%\. ฉันต้องการเริ่มสคริปต์โดยเปลี่ยนเส้นทางไปยังเดสก์ท็อปผู้ใช้ ฉันสามารถทำได้ด้วยความช่วยเหลือจากด้านบนและที่อื่น ๆ โดยใช้แอปเพล็ตget-location

คุณอาจมีวิธีอื่นหรือดีกว่าที่จะทำ แต่วิธีนี้ใช้ได้ผลสำหรับฉัน:

$Path = Get-Location

Set-Location $Path\Desktop

1
ยินดีต้อนรับสู่Stack Overflow ! Set-Location Desktopนี้จะเทียบเท่ากับ ( Get-Locationเพียงส่งกลับที่ตั้งปัจจุบันซึ่งเป็นนัยให้Set-Locationกับทางญาติ.)
jpaugh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.