Batch script: how to check for admin rights

How do I check if the current batch script has admin rights?

I know how to make it call itself with runas but not how to check for admin rights. The only solutions I've seen are crude hack jobs or use external programs. Well, actually I don't care if it is a hack job as long as it works on Windows XP and newer.


Issues

blak3r / Rushyo's solution works fine for everything except Windows 8. Running AT on Windows 8 results in:

The AT command has been deprecated. Please use schtasks.exe instead.

The request is not supported.

(see screenshot #1) and will return %errorLevel% 1.

 

Research

So, I went searching for other commands that require elevated permissions. rationallyparanoid.com had a list of a few, so I ran each command on the two opposite extremes of current Windows OSs (XP and 8) in the hopes of finding a command that would be denied access on both OSs when run with standard permissions.

Eventually, I did find one - NET SESSION. A true, clean, universal solution that doesn't involve:

  • the creation of or interaction with data in secure locations
  • analyzing data returned from FOR loops
  • searching strings for "Administrator"
  • using AT (Windows 8 incompatible) or WHOAMI (Windows XP incompatible).

Each of which have their own security, usability, and portability issues.

 

Testing

I've independently confirmed that this works on:

  • Windows XP, x86
  • Windows XP, x64
  • Windows Vista, x86
  • Windows Vista, x64
  • Windows 7, x86
  • Windows 7, x64
  • Windows 8, x86
  • Windows 8, x64
  • Windows 10 v1909, x64

(see screenshot #2)

 

Implementation / Usage

So, to use this solution, simply do something like this:

@echo off
goto check_Permissions

:check_Permissions
    echo Administrative permissions required. Detecting permissions...

    net session >nul 2>&1
    if %errorLevel% == 0 (
        echo Success: Administrative permissions confirmed.
    ) else (
        echo Failure: Current permissions inadequate.
    )

    pause >nul

Available here, if you're lazy: https://dl.dropbox.com/u/27573003/Distribution/Binaries/check_Permissions.bat

 

Explanation

NET SESSION is a standard command used to "manage server computer connections. Used without parameters, [it] displays information about all sessions with the local computer."

So, here's the basic process of my given implementation:

  1. @echo off
    • Disable displaying of commands
  2. goto check_Permissions
    • Jump to the :check_Permissions code block
  3. net session >nul 2>&1
    • Run command
    • Hide visual output of command by
      1. Redirecting the standard output (numeric handle 1 / STDOUT) stream to nul
      2. Redirecting the standard error output stream (numeric handle 2 / STDERR) to the same destination as numeric handle 1
  4. if %errorLevel% == 0
    • If the value of the exit code (%errorLevel%) is 0 then this means that no errors have occurred and, therefore, the immediate previous command ran successfully
  5. else
    • If the value of the exit code (%errorLevel%) is not 0 then this means that errors have occurred and, therefore, the immediate previous command ran unsuccessfully
  6. The code between the respective parenthesis will be executed depending on which criteria is met

 

Screenshots

Windows 8 AT %errorLevel%:

[imgur]

 

NET SESSION on Windows XP x86 - Windows 8 x64:

[imgur]

 

Thank you, @Tilka, for changing your accepted answer to mine. :)


Anders solution worked for me but I wasn't sure how to invert it to get the opposite (when you weren't an admin).

Here's my solution. It has two cases an IF and ELSE case, and some ascii art to ensure people actually read it. :)

Minimal Version

Rushyo posted this solution here: How to detect if CMD is running as Administrator/has elevated privileges?

NET SESSION >nul 2>&1
IF %ERRORLEVEL% EQU 0 (
    ECHO Administrator PRIVILEGES Detected! 
) ELSE (
    ECHO NOT AN ADMIN!
)

Version which adds an Error Messages, Pauses, and Exits

@rem ----[ This code block detects if the script is being running with admin PRIVILEGES If it isn't it pauses and then quits]-------
echo OFF
NET SESSION >nul 2>&1
IF %ERRORLEVEL% EQU 0 (
    ECHO Administrator PRIVILEGES Detected! 
) ELSE (
   echo ######## ########  ########   #######  ########  
   echo ##       ##     ## ##     ## ##     ## ##     ## 
   echo ##       ##     ## ##     ## ##     ## ##     ## 
   echo ######   ########  ########  ##     ## ########  
   echo ##       ##   ##   ##   ##   ##     ## ##   ##   
   echo ##       ##    ##  ##    ##  ##     ## ##    ##  
   echo ######## ##     ## ##     ##  #######  ##     ## 
   echo.
   echo.
   echo ####### ERROR: ADMINISTRATOR PRIVILEGES REQUIRED #########
   echo This script must be run as administrator to work properly!  
   echo If you're seeing this after clicking on a start menu icon, then right click on the shortcut and select "Run As Administrator".
   echo ##########################################################
   echo.
   PAUSE
   EXIT /B 1
)
@echo ON

Works on WinXP --> Win8 (including 32/64 bit versions).

EDIT: 8/28/2012 Updated to support Windows 8. @BenHooper pointed this out in his answer below. Please upvote his answer.


More issues

As pointed out by @Lectrode, if you try to run the net session command while the Server service is stopped, you receive the following error message:

The Server service is not started.

More help is available by typing NET HELPMSG 2114

In this case the %errorLevel% variable will be set to 2.

Note The Server service is not started while in Safe Mode (with or without networking).

Looking for an alternative

Something that:

  • can be run out of the box on Windows XP and later (32 and 64 bit);
  • doesn't touch the registry or any system file/folder;
  • works regardless of the system locale;
  • gives correct results even in Safe Mode.

So I booted a vanilla Windows XP virtual machine and I started scrolling through the list of applications in the C:\Windows\System32 folder, trying to get some ideas. After trials and errors, this is the dirty (pun intended) approach I've come up with:

fsutil dirty query %systemdrive% >nul

The fsutil dirty command requires admin rights to run, and will fail otherwise. %systemdrive% is an environment variable which returns the drive letter where the operating system is installed. The output is redirected to nul, thus ignored. The %errorlevel% variable will be set to 0 only upon successful execution.

Here is what the documentation says:

Fsutil dirty

Queries or sets a volume's dirty bit. When a volume's dirty bit is set, autochk automatically checks the volume for errors the next time the computer is restarted.

Syntax

fsutil dirty {query | set} <VolumePath>

Parameters

query           Queries the specified volume's dirty bit.
set             Sets the specified volume's dirty bit.
<VolumePath>    Specifies the drive name followed by a colon or GUID.

Remarks

A volume's dirty bit indicates that the file system may be in an inconsistent state. The dirty bit can be set because:

  • The volume is online and it has outstanding changes.
  • Changes were made to the volume and the computer was shut down before the changes were committed to the disk.
  • Corruption was detected on the volume.

If the dirty bit is set when the computer restarts, chkdsk runs to verify the file system integrity and to attempt to fix any issues with the volume.

Examples

To query the dirty bit on drive C, type:

fsutil dirty query C:

Further research

While the solution above works from Windows XP onwards, it's worth adding that Windows 2000 and Windows PE (Preinstalled Environment) don't come with fsutil.exe, so we have to resort to something else.

During my previous tests I noticed that running the sfc command without any parameters would either result in:

  • an error, if you didn't have enough privileges;
  • a list of the available parameters and their usage.

That is: no parameters, no party. The idea is that we can parse the output and check if we got anything but an error:

sfc 2>&1 | find /i "/SCANNOW" >nul

The error output is first redirected to the standard output, which is then piped to the find command. At this point we have to look for the only parameter that is supported in all Windows version since Windows 2000: /SCANNOW. The search is case insensitive, and the output is discarded by redirecting it to nul.

Here's an excerpt from the documentation:

Sfc

Scans and verifies the integrity of all protected system files and replaces incorrect versions with correct versions.

Remarks

You must be logged on as a member of the Administrators group to run sfc.exe.

Sample Usage

Here are some paste-and-run examples:

Windows XP and later

@echo off

call :isAdmin
if %errorlevel% == 0 (
echo Running with admin rights.
) else (
echo Error: Access denied.
)

pause >nul
exit /b

:isAdmin
fsutil dirty query %systemdrive% >nul
exit /b

Windows 2000 / Windows PE

@echo off

call :isAdmin
if %errorlevel% == 0 (
echo Running with admin rights.
) else (
echo Error: Access denied.
)

pause >nul
exit /b

:isAdmin
sfc 2>&1 | find /i "/SCANNOW" >nul
exit /b

Applies to

  • Windows 2000
  • Windows XP
  • Windows Vista
  • Windows 7
  • Windows 8
  • Windows 8.1
    ---
  • Windows PE

two more ways - fast and backward compatible .

fltmc >nul 2>&1 && (
  echo has admin permissions
) || (
  echo has NOT admin permissions
)

fltmc command is available on every windows system since XP so this should be pretty portable.


One more really fast solution tested on XP,8.1,7 - there's one specific variable =:: which is presented only if the console session has no admin privileges.As it is not so easy to create variable that contains = in it's name this is comparatively reliable way to check for admin permission (it does not call external executables so it performs well)

setlocal enableDelayedExpansion
set "dv==::"
if defined !dv! ( 
   echo has NOT admin permissions
) else (
   echo has admin permissions
)

If you want use this directly through command line ,but not from a batch file you can use:

set ^"|find "::"||echo has admin permissions