'Windows batch script - requesting UAC admin rights in a log-friendly way

I'm requesting admin with the following in a batch script:

: BatchGotAdmin
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    set params = %*:"=""
    echo UAC.ShellExecute "%~s0", "%params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
    pushd "%CD%"
    CD /D "%~dp0"

When piping the output to a logfile - this point in the script cuts it off. Is there a way to change to script to have the same effect (requesting UAC admin rights in the middle of a batch script) whilst still keeping the log file going as expected?



Solution 1:[1]

I know this question is 8 months old, but as you don't seem to have got a good answer I thought I'd chip in anyway as I cam across it looking for something else.

I would agree with Magoo as I'm also not sure if the set params line is doing what you want. I would suggest trying this instead:

At the start of your UAC:

:UACPrompt
if '%1'=='UACdone' (shift & goto gotAdmin)

Then after your original line:

echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
echo UAC.ShellExecute "%~0", "UACdone", "", "runas", 1 >> "%temp%\getadmin.vbs"

For clarity that should then make the entire script look as so:

: BatchGotAdmin
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    if '%1'=='UACdone' (shift & goto gotAdmin)
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    echo UAC.ShellExecute "%~0", "UACdone", "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
    pushd "%CD%"
    CD /D "%~dp0"

Put this at the top of your script and if you don't have admin rights it should spawn another instance requesting admin rights. All you need to do is put your commands below. This has the added advantage of not requiring you to redistribute any additional tools along with the script.

Solution 2:[2]

I'm concerned about the sequence

set params = %*:"=""
echo UAC.ShellExecute "%~s0", "%params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

What thus should do is set the environment variable "params[space]" to the value [space]command-parameters supplied:"=""

In the following line, you're using the environment variable "params" which would likely not be set. Hence, I'm not sure that getadmin.vbs is being correctly generated.

spaces on ANY side of a SET are important...

Solution 3:[3]

My approach would be to check for elevation in the shell script and fail if not elevated; e.g.

@echo off
setlocal enableextensions
isadmin -q
if %ERRORLEVEL% NEQ 1 goto :ERROR
...
[do stuff requiring elevation]
....
goto :DONE

:ERROR
echo You must run this script from an elevated command window.

:DONE
endlocal

You can get isadmin.exe from here: Windows Admin Script Tools

Bill

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 fileinsert
Solution 2 Magoo
Solution 3 Bill_Stewart