¿Cómo detectar si CMD se está ejecutando como administrador / tiene privilegios elevados?

101

Desde dentro de un archivo por lotes, me gustaría probar si estoy ejecutando con privilegios de administrador / elevados.

El nombre de usuario no cambia cuando se selecciona "Ejecutar como administrador", por lo que no funciona.

Si hubiera un comando disponible universalmente, que no tiene ningún efecto, pero requiere privilegios administrativos, entonces podría ejecutarlo y buscar un código de error para probar los privilegios. Hasta ahora, no he encontrado tal comando. Los comandos que he encontrado parecen devolver un solo código de error no específico, que podría indicar cualquier cosa, y son propensos a fallar por una variedad de razones.

Solo me importa Windows 7, aunque la compatibilidad con sistemas operativos anteriores estaría bien.

Jeff
fuente
Un truco sería intentar hacerlo echo > somefileen un directorio que requeriría privilegios de administrador. produciría un archivo como efecto secundario, pero podría verificar si hay colisiones y crear un nombre de archivo único como solución.
Marc B
1
[puede encontrar un lote autoelevable aquí] [1] [1]: stackoverflow.com/questions/4051883/…
Amr Ali
1
@npocmaka, la pregunta que vinculó es en realidad el duplicado de esta;) (2013 vs. 2011)
Matthieu

Respuestas:

62

ADENDA : Para Windows 8 esto no funcionará; vea esta excelente respuesta en su lugar.


Encontré esta solución aquí: http://www.robvanderwoude.com/clevertricks.php

AT > NUL
IF %ERRORLEVEL% EQU 0 (
    ECHO you are Administrator
) ELSE (
    ECHO you are NOT Administrator. Exiting...
    PING 127.0.0.1 > NUL 2>&1
    EXIT /B 1
)

Suponiendo que eso no funcione y ya que estamos hablando de Win7, podría usar lo siguiente en Powershell si es adecuado:

$principal = new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())
$principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)

Si no es así (y probablemente no, ya que propuso explícitamente archivos por lotes), entonces podría escribir lo anterior en .NET y devolver un código de salida de un exe basado en el resultado para que lo use su archivo por lotes.

Rushyo
fuente
4
¡El comando AT es perfecto! Tu Google-fu es superior a mi Google-fu. ;-)
Jeff
2
+1 @Rushyo, extendí un poco tu solución y la publiqué aquí, ya que esa es la que encontré originalmente. ¡Gracias! stackoverflow.com/questions/4051883/…
blak3r
16
ATno funciona en Windows 8, pero encontré una solución mejor. Lo he publicado como respuesta a otra pregunta, aquí: stackoverflow.com/questions/4051883/… .
mitofechelon
4
Recomiendo whoami / grupos | Findstr / b BUILTIN \ Admin | findtr / c: "Grupo habilitado" && echo "¡Tengo un administrador!" - trabajar en 95, 98, 2000, xp, vista, 7, 8! (Del comentario "Me gusta la sugerencia de Rushyo de usar AT ...")
barwnikk
1
Me gusta pingreemplazar la falta sleep:)
Matthieu
96

Este truco solo requiere un comando: escriba net sessionen el símbolo del sistema.

Si NO es un administrador , recibirá un mensaje de acceso denegado.

System error 5 has occurred.

Access is denied.

Si es administrador , recibirá un mensaje diferente, el más común es:

There are no entries in the list.

Desde MS Technet :

Utilizada sin parámetros, net session muestra información sobre todas las sesiones con la computadora local.

Ambrose Leung
fuente
Eso es funcionalmente idéntico a la respuesta de Rushyo, que usó el comando AT.
Jeff
12
En Windows 8.1, se prefiere a AT, ya que AT está en desuso. Usar la respuesta de Rushyo pero sustituir AT con net session o net.exe funciona perfectamente para mí.
kayleeFrye_onDeck
Esta parece la forma más fácil de hacer esto en el símbolo del sistema (que es diferente al archivo por lotes).
enderland
2
Solo se imprime There are no entries in the list.en Windows 10 Pro
gman
1
en un archivo por lotes use algo como eso:net session >nul 2>&1 || (echo not admin&goto :eof)
anilech
27

Me gusta la sugerencia de Rushyo de usar AT, pero esta es otra opción:

whoami /groups | findstr /b BUILTIN\Administrators | findstr /c:"Enabled group" && goto :isadministrator

Este enfoque también le permitiría distinguir entre un administrador no administrador y un administrador no elevado si así lo desea. Los administradores no elevados todavía tienen BUILTIN \ Administrators en la lista de grupos, pero no está habilitado.

Sin embargo, esto no funcionará en algunos sistemas de idiomas distintos del inglés. En su lugar, intente

whoami /groups | findstr /c:" S-1-5-32-544 " | findstr /c:" Enabled group" && goto :isadministrator

(Esto debería funcionar en Windows 7, pero no estoy seguro de las versiones anteriores).

Harry Johnston
fuente
1
En la versión polaca, tengo: BUILTIN \ Administratorzy, así que recomiendo: whoami / groups | Findstr / b BUILTIN \ Admin | foundtr / c: "Grupo habilitado" && goto: isadministrator
barwnikk
@barwnikk, recomiendo whoami/groupsy luego escanear las líneas manualmente. No tomaría mucho tiempo y el comando encaja en su cerebro.
Pacerier
@Pacerier: el punto de la pregunta es detectar la elevación en un archivo por lotes . Si una persona está en la línea de comando, todo lo que necesita hacer es mirar el título de la ventana, que siempre comienza con "Administrador:" si está elevado.
Harry Johnston
@HarryJohnston, Wow no se dio cuenta de eso. ¿Aparece el título "Administrador" para todas las versiones de Windows?
Pacerier
@Pacerier: todas las versiones actuales (Vista en adelante).
Harry Johnston
24

Más o menos lo que otros han puesto antes, pero como una línea que se puede poner al principio de un comando por lotes. (Bueno, generalmente después de @echo off.)

net.exe session 1>NUL 2>NUL || (Echo This script requires elevated rights. & Exit /b 1)
geek_01
fuente
2
Esta es la versión actualizada y oculta muy bien la salida irrelevante de net.exe
andersand
2
Funciona bien en Windows 10.
James Pack
Funcionó muy bien, solo modifiqué el final de & Timeout / t 10 & Exit / b 1) para que en un archivo por lotes la ventana no desaparezca instantáneamente.
WhoIsRich
12

La forma más fácil de hacer esto en Vista, Win 7 y superior es enumerar los grupos de tokens y buscar el nivel de integridad actual (o el sid del administrador, si solo la pertenencia al grupo es importante):

Compruebe si estamos ejecutando elevado:

whoami /groups | find "S-1-16-12288" && Echo I am running elevated, so I must be an admin anyway ;-)

Comprueba si pertenecemos a administradores locales:

whoami /groups | find "S-1-5-32-544" && Echo I am a local admin

Compruebe si pertenecemos a administradores de dominio:

whoami /groups | find "-512 " && Echo I am a domain admin

El siguiente artículo enumera los SID de nivel de integridad que usa Windows: http://msdn.microsoft.com/en-us/library/bb625963.aspx

Martin Binder
fuente
whoami / groups tiene un caso límite en el que obtienes la información incorrecta. Ver stackoverflow.com/questions/4051883/…
zumalifeguard
7

Aquí hay una pequeña modificación de la respuesta de Harry que se enfoca en el estatus elevado; Estoy usando esto al comienzo de un archivo install.bat:

set IS_ELEVATED=0
whoami /groups | findstr /b /c:"Mandatory Label\High Mandatory Level" | findstr /c:"Enabled group" > nul: && set IS_ELEVATED=1
if %IS_ELEVATED%==0 (
    echo You must run the command prompt as administrator to install.
    exit /b 1
)

Esto definitivamente funcionó para mí y el principio parece ser sólido; de Chris Jackson de MSFT :

Cuando se está ejecutando elevado, su token contiene una ACE llamada Etiqueta obligatoria \ Nivel obligatorio alto.

Hugh
fuente
whoami / groups tiene un caso límite en el que obtienes la información incorrecta. Ver stackoverflow.com/questions/4051883/…
zumalifeguard
7

la solución:

at >nul
if %ErrorLevel% equ 0 ( echo Administrator ) else ( echo NOT Administrator )

no funciona en Windows 10

para todas las versiones de Windows puede hacerlo:

openfiles >nul 2>&1
if %ErrorLevel% equ 0 ( echo Administrator ) else ( echo NOT Administrator )
ipAlex
fuente
6

Leí muchas (¿la mayoría?) De las respuestas, luego desarrollé un archivo bat que me funciona en Win 8.1. Pensé en compartirlo.

setlocal
set runState=user
whoami /groups | findstr /b /c:"Mandatory Label\High Mandatory Level" > nul && set runState=admin
whoami /groups | findstr /b /c:"Mandatory Label\System Mandatory Level" > nul && set runState=system
echo Running in state: "%runState%"
if not "%runState%"=="user" goto notUser
  echo Do user stuff...
  goto end
:notUser
if not "%runState%"=="admin" goto notAdmin
  echo Do admin stuff...
  goto end
:notAdmin
if not "%runState%"=="system" goto notSystem
  echo Do admin stuff...
  goto end
:notSystem
echo Do common stuff...
:end

Espero que alguien encuentre esto útil :)

GeoffH
fuente
whoami / groups tiene un caso límite en el que obtienes la información incorrecta. Ver stackoverflow.com/questions/4051883/…
zumalifeguard
¡Gracias por esto! La otra solución "whoami" no me funcionó en Windows 8.1. Este lo hizo.
Ryan
1

Sé que llego muy tarde a esta fiesta, pero aquí está mi única línea para determinar la administración.

No se basa en el nivel de error, solo en systeminfo:

for /f "tokens=1-6" %%a in ('"net user "%username%" | find /i "Local Group Memberships""') do (set admin=yes & if not "%%d" == "*Administrators" (set admin=no) & echo %admin%)

Devuelve sí o no, según el estado de administrador del usuario ...

También establece el valor de la variable "admin" para que sea igual a sí o no según corresponda.

usuario1
fuente
Esto solo funcionará si el usuario es un miembro directo del grupo local de administradores. Si el usuario es miembro de un grupo de dominio (por ejemplo, "Administradores de dominio") que es miembro del grupo de Administradores, no funcionará.
Harry Johnston
1

Si está ejecutando como un usuario con derechos de administrador, la variable de entorno SessionName NO se definirá y aún no tiene derechos de administrador al ejecutar un archivo por lotes.

Debe usar el comando "net session" y buscar un código de retorno de error "0" para verificar los derechos de administrador.

Ejemplo; - la primera declaración de eco es el carácter de campana net session >nul 2>&1 if not %errorlevel%==0 (echo echo You need to start over and right-click on this file, echo then select "Run as administrator" to be successfull. echo.&pause&exit)

Wolfgang
fuente
0

Aquí hay un método simple que he usado en Windows 7 a Windows 10. Básicamente, simplemente uso el comando "SI EXISTE" para buscar la carpeta Windows \ System32 \ WDI \ LogFiles. La carpeta WDI existe en cada instalación de Windows desde al menos 7 en adelante, y requiere privilegios de administrador para acceder. La carpeta WDI siempre tiene una carpeta LogFiles dentro. Por lo tanto, ejecutar "SI EXISTE" en la carpeta WDI \ LogFiles devolverá verdadero si se ejecuta como administrador y falso si no se ejecuta como administrador. Esto se puede usar en un archivo por lotes para verificar el nivel de privilegios y pasar a los comandos que desee en función de ese resultado.

Aquí hay un breve fragmento de código de ejemplo:

IF EXIST %SYSTEMROOT%\SYSTEM32\WDI\LOGFILES GOTO GOTADMIN
(Commands for running with normal privileges)

:GOTADMIN
(Commands for running with admin privileges)

Tenga en cuenta que este método asume que los permisos de seguridad predeterminados no se han modificado en la carpeta WDI (lo que es poco probable que suceda en la mayoría de las situaciones, pero consulte la advertencia n. ° 2 a continuación). Incluso en ese caso, es simplemente una cuestión de modificar el código para buscar un archivo / carpeta común diferente que requiera acceso de administrador (System32 \ config \ SAM puede ser un buen candidato alternativo), o incluso podría crear el suyo propio específicamente para eso. propósito.

Sin embargo, hay dos advertencias sobre este método:

  1. Deshabilitar UAC probablemente lo romperá con el simple hecho de que todo se ejecutará como administrador de todos modos.

  2. Intentar abrir la carpeta WDI en el Explorador de Windows y luego hacer clic en "Continuar" cuando se le solicite agregará derechos de acceso permanentes para esa cuenta de usuario, rompiendo así mi método. Si esto sucede, se puede solucionar eliminando la cuenta de usuario de los permisos de seguridad de la carpeta WDI. Si por alguna razón el usuario DEBE poder acceder a la carpeta WDI con el Explorador de Windows, entonces tendrá que modificar el código para verificar una carpeta diferente (como se mencionó anteriormente, crear la suya propia específicamente para este propósito puede ser una buena opción) .

Entonces, admito que mi método no es perfecto ya que puede romperse, pero es un método relativamente rápido que es fácil de implementar, es igualmente compatible con todas las versiones de Windows 7, 8 y 10, y siempre que esté consciente de las advertencias mencionadas. sido 100% efectivo para mí.

Torin Darkflight
fuente
0

Funciona para Win7 Enterprise y Win10 Enterprise

@if DEFINED SESSIONNAME (
    @echo.
    @echo You must right click to "Run as administrator"
    @echo Try again
    @echo.
    @pause
    @goto :EOF
)
englebart
fuente