Como detectar se o CMD está sendo executado como administrador / possui privilégios elevados?

101

De dentro de um arquivo em lote, gostaria de testar se estou executando com privilégios de administrador / elevados.

O nome de usuário não muda quando "Executar como administrador" é selecionado, então isso não funciona.

Se houvesse um comando disponível universalmente, que não tivesse efeito, mas exigisse privilégios administrativos, eu poderia executá-lo e verificar se há um código de erro para testar os privilégios. Até agora, não encontrei esse comando. Os comandos que encontrei parecem retornar um único código de erro não específico, que pode indicar qualquer coisa, e estão sujeitos a falhas por vários motivos.

Eu só me importo com o Windows 7, embora o suporte de sistemas operacionais anteriores fosse bom.

Jeff
fonte
Um hack seria tentar fazer echo > somefileem um diretório que exigiria privilégios de administrador. ele produziria um arquivo como um efeito colateral, mas você poderia verificar se há colisões e criar um nome de arquivo exclusivo como uma solução alternativa.
Marc B
1
[você pode encontrar um lote autoelevante aqui] [1] [1]: stackoverflow.com/questions/4051883/…
Amr Ali
1
@npocmaka a pergunta que você vinculou é na verdade uma duplicata desta;) (2013 vs. 2011)
Matthieu

Respostas:

62

ADENDO : Para Windows 8 isso não funcionará; veja esta excelente resposta em vez disso.


Encontre esta solução aqui: 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
)

Supondo que isso não funcione, e como estamos falando de Win7, você pode usar o seguinte no Powershell, se for adequado:

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

Se não (e provavelmente não, já que você propôs explicitamente os arquivos em lote), você pode escrever o código acima em .NET e retornar um código de saída de um exe com base no resultado para seu arquivo em lote usar.

Rushyo
fonte
4
O comando AT é perfeito! Seu Google-fu é superior ao meu Google-fu. ;-)
Jeff
2
+1 @Rushyo, eu estendi um pouco sua solução e a postei aqui, já que foi essa que encontrei originalmente. Obrigado! stackoverflow.com/questions/4051883/…
blak3r
16
ATnão funciona no Windows 8, mas encontrei uma solução melhor. Eu postei como uma resposta a outra pergunta, aqui: stackoverflow.com/questions/4051883/… .
mythofechelon
4
Eu recomendo whoami / groups | findstr / b BUILTIN \ Admin | findstr / c: "Grupo habilitado" && echo "Eu tenho um administrador!" - trabalhar em 95, 98, 2000, XP, Vista, 7, 8! (Do comentário "Eu gosto da sugestão de Rushyo de usar AT ...")
barwnikk
1
Gosto pingde substituir faltando sleep:)
Matthieu
96

Este truque requer apenas um comando: digite net sessionno prompt de comando.

Se você NÃO for um administrador , receberá uma mensagem de acesso negado.

System error 5 has occurred.

Access is denied.

Se você É um administrador , receberá uma mensagem diferente, sendo a mais comum:

There are no entries in the list.

Da MS Technet :

Usado sem parâmetros, net session exibe informações sobre todas as sessões com o computador local.

Ambrose Leung
fonte
Isso é funcionalmente idêntico à resposta de Rushyo, que usou o comando AT.
Jeff
12
No Windows 8.1, é preferível ao AT, pois o AT está obsoleto. Usar a resposta de Rushyo, mas substituir AT por sessão net ou sessão net.exe funciona perfeitamente para mim.
kayleeFrye_onDeck
Esta parece ser a maneira mais fácil de fazer isso no prompt de comando (que é diferente do arquivo em lote, no entanto).
enderland
2
Apenas imprime There are no entries in the list.no Windows 10 Pro
gman
1
em um arquivo de lote, use algo assim:net session >nul 2>&1 || (echo not admin&goto :eof)
anilech
27

Gosto da sugestão de Rushyo de usar AT, mas esta é outra opção:

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

Essa abordagem também permite que você faça a distinção entre um não administrador e um administrador não elevado, se desejar. Os administradores não elevados ainda têm BUILTIN \ Administradores na lista de grupos, mas não está habilitado.

No entanto, isso não funcionará em alguns sistemas de idioma diferente do inglês. Em vez disso, tente

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

(Isso deve funcionar no Windows 7, mas não tenho certeza sobre as versões anteriores.)

Harry Johnston
fonte
1
Na versão polonesa, tenho: BUILTIN \ Administratorzy, então, recomendo: whoami / groups | findstr / b BUILTIN \ Admin | findstr / c: "Grupo habilitado" && goto: isadministrator
barwnikk
@barwnikk, eu recomendo whoami/groupse então escaneie as linhas manualmente. Não demoraria muito e o comando caberia em seu cérebro.
Pacerier
@Pacerier: o objetivo da questão é detectar a elevação em um arquivo de lote . Se uma pessoa estiver na linha de comando, tudo que ela precisa fazer é olhar o título da janela, que sempre inicia "Administrador:" se você estiver elevado.
Harry Johnston
@HarryJohnston, Uau, não percebi isso. O título de "Administrador" aparece em todas as versões do Windows?
Pacerier
@Pacerier: todas as versões atuais (Vista em diante).
Harry Johnston
24

Praticamente o que outros colocaram antes, mas como uma linha que pode ser colocada no início de um comando de lote. (Bem, geralmente após @echo off.)

net.exe session 1>NUL 2>NUL || (Echo This script requires elevated rights. & Exit /b 1)
geek_01
fonte
2
Esta é a versão atualizada e oculta a saída irrelevante de net.exe muito bem
andersand
2
Funciona bem no Windows 10.
James Pack de
Funcionou muito bem, apenas ajustou o final para & Timeout / t 10 & Exit / b 1) para que em um arquivo de lote a janela não desapareça instantaneamente.
WhoIsRich
12

A maneira mais fácil de fazer isso no Vista, Win 7 e superior é enumerar grupos de tokens e procurar o nível de integridade atual (ou o lado do administrador, se apenas a associação ao grupo for importante):

Verifique se estamos executando elevados:

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

Verifique se pertencemos a administradores locais:

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

Verifique se pertencemos a administradores de domínio:

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

O seguinte artigo lista os SIDs de nível de integridade usados ​​pelas janelas: http://msdn.microsoft.com/en-us/library/bb625963.aspx

Martin Binder
fonte
whoami / groups tem um caso extremo em que você obtém as informações erradas. Consulte stackoverflow.com/questions/4051883/…
zumalifeguard
7

Aqui está uma ligeira modificação da resposta de Harry que se concentra no status elevado; Estou usando isso no início de um arquivo 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
)

Isso definitivamente funcionou para mim e o princípio parece ser bom; de Chris Jackson da MSFT :

Quando você está executando elevado, seu token contém uma ACE chamada Rótulo obrigatório \ Nível obrigatório alto.

Hugh
fonte
whoami / groups tem um caso extremo em que você obtém as informações erradas. Consulte stackoverflow.com/questions/4051883/…
zumalifeguard
7

a solução:

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

não funciona no Windows 10

para todas as versões do Windows pode ser:

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

Eu li muitas (a maioria?) Das respostas, então desenvolvi um arquivo bat que funciona para mim no Win 8.1. Pensei em compartilhar.

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 alguém ache isso útil :)

GeoffH
fonte
whoami / groups tem um caso extremo em que você obtém as informações erradas. Consulte stackoverflow.com/questions/4051883/…
zumalifeguard
Obrigado por isso! A outra solução "whoami" não funcionou para mim no Windows 8.1. Este sim.
Ryan
1

Eu sei que estou muito atrasado para esta festa, mas aqui está minha única linha para determinar a função administrativa.

Não depende do nível de erro, apenas de 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%)

Ele retorna sim ou não, dependendo do status de administrador do usuário ...

Ele também define o valor da variável "admin" como igual a sim ou não, de acordo.

usuário1
fonte
Isso só funcionará se o usuário for um membro direto do grupo local de Administradores. Se o usuário for membro de um grupo de domínio (por exemplo, "Admins. Do domínio") que seja membro do grupo Administradores, não funcionará.
Harry Johnston
1

Se você estiver executando como um usuário com direitos de administrador, a variável de ambiente SessionName NÃO será definida e você ainda não tem direitos de administrador ao executar um arquivo em lote.

Você deve usar o comando "net session" e procurar um código de retorno de erro "0" para verificar os direitos do administrador.

Exemplo; - a primeira declaração de eco é o caractere de sino 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
fonte
0

Aqui está um método simples que usei no Windows 7 ao Windows 10. Basicamente, eu simplesmente uso o comando "IF EXIST" para verificar a pasta Windows \ System32 \ WDI \ LogFiles. A pasta WDI existe em todas as instalações do Windows, de pelo menos 7 em diante, e requer privilégios de administrador para acessá-la. A pasta WDI sempre tem uma pasta LogFiles dentro dela. Portanto, executar "IF EXIST" na pasta WDI \ LogFiles retornará verdadeiro se executado como administrador e falso se não for executado como administrador. Isso pode ser usado em um arquivo em lote para verificar o nível de privilégio e desviar para quaisquer comandos que você deseja com base nesse resultado.

Aqui está um breve trecho de código de exemplo:

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

:GOTADMIN
(Commands for running with admin privileges)

Lembre-se de que este método assume que as permissões de segurança padrão não foram modificadas na pasta WDI (o que é improvável de acontecer na maioria das situações, mas consulte a advertência nº 2 abaixo). Mesmo nesse caso, é simplesmente uma questão de modificar o código para verificar se há um arquivo / pasta comum diferente que requer acesso de administrador (System32 \ config \ SAM pode ser um bom candidato alternativo), ou você pode até mesmo criar seu próprio especificamente para isso objetivo.

No entanto, existem duas advertências sobre esse método:

  1. Desativar o UAC provavelmente irá quebrá-lo pelo simples fato de que tudo seria executado como administrador de qualquer maneira.

  2. Tentar abrir a pasta WDI no Windows Explorer e clicar em "Continuar" quando solicitado adicionará direitos de acesso permanentes para essa conta de usuário, quebrando assim meu método. Se isso acontecer, pode ser corrigido removendo a conta do usuário das permissões de segurança da pasta WDI. Se, por algum motivo, o usuário PRECISA ser capaz de acessar a pasta WDI com o Windows Explorer, será necessário modificar o código para verificar uma pasta diferente (conforme mencionado acima, criar sua própria pasta especificamente para esse fim pode ser uma boa escolha) .

Portanto, admito que meu método não é perfeito, pois pode ser quebrado, mas é um método relativamente rápido e fácil de implementar, é igualmente compatível com todas as versões do Windows 7, 8 e 10, e desde que eu esteja ciente das advertências mencionadas foi 100% eficaz para mim.

Torin Darkflight
fonte
0

Funciona para Win7 Enterprise e Win10 Enterprise

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