¿Cómo obtengo el nombre de usuario actual en Windows PowerShell?

Respuestas:

398

Lo encontré:

$env:UserName

También hay:

$env:UserDomain
$env:ComputerName
Thomas Bratt
fuente
10
Una alternativa rápida y sucia sería $env:usernamerecuperar el nombre de usuario de la variable de entorno correspondiente.
guillermooo
77
Creo que $ env: username y [Environment] :: UserName apuntan a lo mismo.
Cephas
16
Gracias por volver a responder tu propia pregunta. Nada más frustrante cuando alguien descubre la respuesta por sí mismo y simplemente responde: "No importa, ¡lo tengo!"
Matt DiTrolio
66
@MattDiTrolio Eso ciertamente es frustrante, pero ¿crees que no hay nada más frustrante que eso?
Code Jockey
55
@CodeJockey Nada. No en la historia de siempre. :)
Matt DiTrolio
181
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Mark Seemann
fuente
16
Esta es la respuesta más segura porque $env:USERNAMEpuede ser alterada por el usuario, pero esto no se dejará engañar al hacerlo.
Kevin Panko
66
@KevinPanko Es cierto, pero en el punto en que no puede confiar en su usuario, hay otras preguntas más filosóficas que deben hacerse. ;-)
jpaugh
44
Este método incluye el nombre de dominio y el nombre de usuario. Definitivamente beneficioso si tienes múltiples dominios en juego.
Ryan Gates
Funciona como se esperaba. Probado para la reserva de dirección url.
Marek Bar
Además, esto también parece funcionar en PowerShell 6, lo que significa que es compatible con varias plataformas (.Net Standard). Pensé que valía la pena mencionarlo, ya que lo cuestioné cuando vi el espacio de nombres.
deadlydog
120

Pensé que sería valioso resumir y comparar las respuestas dadas.

Si desea acceder a la variable de entorno :

(opción más fácil / más corta / memorable)

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

Si desea acceder al token de acceso de Windows :

(opción más confiable)

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

Si desea el nombre del usuario conectado

(en lugar del nombre del usuario que ejecuta la instancia de PowerShell)

  • $(Get-WMIObject -class Win32_ComputerSystem | select username).username- @TwonOfAn en este otro foro

Comparación

El comentario de @Kevin Panko sobre la respuesta de @Mark Seemann trata de elegir una de las categorías sobre la otra:

[El enfoque de token de acceso de Windows] es la respuesta más segura, porque $ env: USERNAME puede ser alterado por el usuario, pero esto no se dejará engañar.

En resumen, la opción de variable de entorno es más sucinta, y la opción de token de acceso de Windows es más confiable.

Tuve que usar el enfoque de token de acceso de Windows de @Mark Seemann en un script de PowerShell que estaba ejecutando desde una aplicación C # con suplantación.

La aplicación C # se ejecuta con mi cuenta de usuario y ejecuta el script de PowerShell como una cuenta de servicio. Debido a una limitación en la forma en que ejecuto el script de PowerShell desde C #, la instancia de PowerShell usa las variables de entorno de mi cuenta de usuario, aunque se ejecuta como el usuario de la cuenta de servicio.

En esta configuración, las opciones de la variable de entorno devuelven el nombre de mi cuenta, y la opción de token de acceso de Windows devuelve el nombre de la cuenta de servicio (que es lo que quería), y la opción de usuario conectado devuelve el nombre de mi cuenta.


Pruebas

Además, si desea comparar las opciones usted mismo, aquí hay un script que puede usar para ejecutar un script como otro usuario. Debe usar el cmdlet Get-Credential para obtener un objeto de credencial y luego ejecutar este script con el script para ejecutarlo como otro usuario como argumento 1 y el objeto de credencial como argumento 2.

Uso:

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

Contenido del script 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
fuente
Para PowerShell 6 en Mac OS X y Linux, [Environment]::UserNamees la mejor opción, ya que funciona multiplataforma. whoamiParece que también funciona, pero depende de la whoamiherramienta que esté disponible en la plataforma.
Florian Feldhaus
Para Powershell 6 en Windows, $env:USERNAMEproduce a SYSTEMmenos que lo ejecute como administrador, mientras que [Environment]::UserName]produce mi nombre de usuario de cualquier manera.
kfsone
1
Parece que el Get-WmiObjectmétodo ya no funciona en pwsh. Incluso trató de importar el módulo de compatibilidad y el Microsoft.PowerShell.Managementque tiene el cmdlet. ¿Alguna idea de lo que está pasando?
not2qubit
Correcto. Hace mucho tiempo que se le pasó a Get-CimInstance por razones de rendimiento ... y CIM se debe usar sobre WMI en v6 por razones de compatibilidad cruzada. Si ve un comando con GWMI, verifique si puede hacer GCIM en su lugar.
Hicsy
105

$env:username es la forma más fácil

Eoin
fuente
Puede asignarlo de esta manera, y crear directorios y lo que no.
Droogans
51

Me gustaría agregar el comando whoami , que básicamente es un buen alias para hacer %USERDOMAIN%\%USERNAME%lo propuesto en otras respuestas.

Write-Host "current user:"
Write-Host $(whoami)
galaktor
fuente
funciona para mí en PS versión 2. ¿Estás diciendo que se cayó en PS3? C: \> powershell Windows PowerShell Copyright (C) 2009 Microsoft Corporation. Todos los derechos reservados. PS C: \> whoami mydomain \
myusername
2
$env:USERNAMEpuede ser alterado por el usuario, pero esto no se dejará engañar haciendo eso.
Kevin Panko
3
Whoami gana por el uso interactivo. Es lo suficientemente corto como para recordar cómo escribirlo sin consultar SO :-)
Iain Samuel McLean Elder
No hay nada en Nano Server. No lo use en scripts, haga lo correcto ( [System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
Yet Another User
whoamiEs un ejecutable. No se puede eliminar de PowerShell. Potencialmente podría eliminarse de Windows, pero todavía está allí a partir de un servidor que no sea Nano Windows 2012.
jpmc26
37

[Environment]::UserNamedevuelve solo el nombre de usuario. Por ejemplo, bob [System.Security.Principal.WindowsIdentity]::GetCurrent().Name devuelve el nombre de usuario, prefijado por su dominio cuando corresponda. Ej. ALGUNA HERENCIA \ bob

WaffleSouffle
fuente
12

He usado $env:username en el pasado, pero un colega señaló que es una variable de entorno y que el usuario puede cambiarlo y, por lo tanto, si realmente desea obtener el nombre de usuario del usuario actual, no debe confiar en él.

Votaría la respuesta de Mark Seemann: [System.Security.Principal.WindowsIdentity] :: GetCurrent (). Name

Pero no se me permite. Con la respuesta de Mark, si solo necesita el nombre de usuario, es posible que tenga que analizarlo ya que en mi sistema, regresa hostname\usernamey en máquinas unidas a un dominio con cuentas de dominio, lo devolverá domain\username.

No lo usaría, whoami.exeya que no está presente en todas las versiones de Windows, y es una llamada a otro binario y puede dar algunos ajustes a los equipos de seguridad.

Dave Hull
fuente
1
Dado que el OP preguntó por Windows-Powershell, eso es válido, pero [Environment]::UserNamees menos tipeado, independiente $env:usernamey multiplataforma: consulte pastebin.com/GsfR6Hrp
kfsone el
12

Ahora que se ha lanzado PowerShell Core (también conocido como v6), y las personas pueden querer escribir scripts multiplataforma, muchas de las respuestas aquí no funcionarán en otra cosa que no sea Windows.

[Environment]::UserName parece ser la mejor manera de obtener el nombre de usuario actual en todas las plataformas compatibles con PowerShell Core si no desea agregar detección de plataforma y carcasa especial a su código.

Edouard Pobre
fuente
10

Basándome en el trabajo de otros aquí:

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

$username

El segundo nombre de usuario es solo para mostrar si lo copia y lo pega.

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

No vi ningún ejemplo basado en Add-Type . Aquí hay uno que usa GetUserName directamente desde 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
fuente
1
Explique qué está haciendo este código y por qué sería más útil que uno de los métodos más cortos.
Benjamin Hubbard
@BenjaminHubbard La pregunta no solicita el método más corto, sino cómo lograr la hazaña con powershell. Esto hace el truco de manera diferente a los otros ejemplos llamando a la función dentro del dll y usando el método Add-Type para acceder a .NET.
Knuckle-Dragger
1
Si bien este es un bloque de código novedoso, sería genial si supiera qué diablos está haciendo. ¿Puedes anotarlo con comentarios, tal vez? ¡Gracias!
jpaugh
1
Casi quería votar, ya que vi el mérito de la propuesta. Sin embargo, el código tiene algunas fallas: introduce un nuevo espacio de nombres, usa una constante mágica (64) cuyo valor no es el que el médico prescribió (debería ser UNLEN+1, y UNLENes 256), ignora cualquier error que pueda ser devuelto por GetUserName (a través de conserva GetLastError, un buen punto), no limpia el búfer de cadena; y probablemente algunos otros. Y como otros dijeron, también faltan comentarios.
AntoineL
-1

Me parece más fácil de usar: cd $ home \ Desktop \

te llevará al escritorio del usuario actual

En mi caso, necesitaba recuperar el nombre de usuario para permitir que el script cambiara la ruta, es decir. c: \ users \% username%. Necesitaba comenzar el script cambiando la ruta al escritorio de los usuarios. Pude hacer esto, con la ayuda de arriba y de otros lugares, usando el applet get-location.

Es posible que tenga otra forma, o incluso mejor, de hacerlo, pero esto funcionó para mí:

$ Path = Get-Location

Establecer ubicación $ Ruta \ Escritorio

Kes tas
fuente
Hacer cualquier suposición basada en el directorio de inicio solo funcionará en condiciones muy específicas.
Raúl Salinas-Monteagudo
Si está trabajando en un terminal de PowerShell y solo quiere saber rápidamente qué usuario es usted, entonces escribir "ls ~" debería ser el truco. Al igual que el póster anterior, puede haber excepciones, y esto definitivamente no es bueno para los guiones, así que use el ejemplo de Edouard Poor en ese caso.
MrBerta
-2

Si está acostumbrado a lotes, puede llamar

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

Básicamente, esto roba el resultado de lo que obtendría si tuviera un archivo por lotes con solo "echo% username%".

Shaws
fuente
1
Estoy votando a favor porque: a) Eres $(...)superfluo: $a = cmd.exe /c echo %username%funciona, b) no es portátil, c) en realidad no responde la pregunta de cómo hacerlo en PowerShell, responde cómo hacerlo en dos, y es mejor darle a un hombre una caña de pescar que darle un pez, por ejemplo powershell puts environment variables into $env, so %username% = $env:username.
kfsone el
-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
fuente
$ contenidos = get-content "cm.txt" ---- $ cuenta = 0 ----- foreach ($ línea en $ cuenta) ---- {$ cuenta = $ cuenta + 1} ---- escritura -host "tienes estas muchas líneas:" $ count
ammy
1. $ a = $ com1, $ com2 ------ write-host "ingrese cm nombre" ---- $ c = readhost ----- write-host $ a [$ c-1] .username , write-host $ a [$ c-1] .password
ammy
$ com1 = objeto nuevo PSobject ----- $ com1 = $ com1 | add-member noteproperty -name username -value 2016
ammy
1
¿Hay alguna razón por la que agrega código como comentarios en su propia respuesta?
aldr
1
¿por qué no edita su respuesta y agrega el código en lugar de dividirlo en comentarios como ese donde nadie lo entenderá?
aldr
-4

En mi caso, necesitaba recuperar el nombre de usuario para permitir que el script cambiara la ruta, es decir. c:\users\%username%\. Necesitaba comenzar el script cambiando la ruta al escritorio de los usuarios. Pude hacer esto, con la ayuda de arriba y de otros lugares, usando el applet get-location .

Es posible que tenga otra forma, o incluso mejor, de hacerlo, pero esto funcionó para mí:

$Path = Get-Location

Set-Location $Path\Desktop
kjp
fuente
1
¡Bienvenido a Stack Overflow ! Esto es equivalente a Set-Location Desktop. ( Get-Locationsimplemente devuelve la ubicación actual, que está implícita para a Set-Locationcon una ruta relativa.)
jpaugh