(This is based on @DarkXphenomenon's answer, which unfortunately had some problems.)
You need to enclose your code within this wrapper:
if _%1_==_payload_ goto :payload
:getadmin
echo %~nx0: elevating self
set vbs=%temp%\getadmin.vbs
echo Set UAC = CreateObject^("Shell.Application"^) >> "%vbs%"
echo UAC.ShellExecute "%~s0", "payload %~sdp0 %*", "", "runas", 1 >> "%vbs%"
"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"
goto :eof
:payload
echo %~nx0: running payload with parameters:
echo %*
echo ---------------------------------------------------
cd /d %2
shift
shift
rem put your code here
rem e.g.: perl myscript.pl %1 %2 %3 %4 %5 %6 %7 %8 %9
goto :eof
This makes batch file run itself as elevated user. It adds two parameters to the privileged code:
word payload
, to indicate this is payload call, i.e. already elevated. Otherwise
it would just open new processes over and over.
directory path where the main script was called. Due to the fact that Windows always
starts elevated cmd.exe in "%windir%\system32", there's no easy way of knowing what
the original path was (and retaining ability to copy your script around without
touching code)
Note: Unfortunately, for some reason shift
does not work for %*
, so if you need
to pass actual arguments on, you will have to resort to the ugly notation I used
in the example (%1 %2 %3 %4 %5 %6 %7 %8 %9
), which also brings in the limit of
maximum of 9 arguments