I have a small script that performs the build and install process on Windows for a Bazaar repository I'm managing. I'm trying to run the script with elevated, administrative privileges from within the Windows shell (cmd.exe)--just as if I'd right-clicked it and chosen Run as Administrator, but without using any method that requires use of the graphical interface.
A batch/WSH hybrid is able to call ShellExecute to display the UAC elevation dialog...
@if (1==1) @if(1==0) @ELSE
@echo off&SETLOCAL ENABLEEXTENSIONS
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"||(
cscript //E:JScript //nologo "%~f0"
@goto :EOF
)
echo.Performing admin tasks...
REM call foo.exe
@goto :EOF
@end @ELSE
ShA=new ActiveXObject("Shell.Application")
ShA.ShellExecute("cmd.exe","/c \""+WScript.ScriptFullName+"\"","","runas",5);
@end
@REM This is my Script
I get some Microsoft JScript compilation: invalid character
error. If this a batch script, why is this happening? Thanks again. –
Chacon ShA.ShellExecute("cmd.exe","/c \""+WScript.ScriptFullName+"\"","","runas",5);
command. –
Reina @if
-@ELSE
-@end
and >nul...
) that makes this a hybrid. –
Pule @ELSE
is not a JScript keyword because it's uppercase. So everything on lines 2 to 14 are 'IF' statements of outer @if
including inner @if
statement, which has it's 'IF' statements on lines 2 to 11. But because inner @if
condition is false, it would never run lines 2 to 11. If you change @ELSE
to lowercase you will break the whole WSH/batch hybrid. –
Alumna @if
statements and the @ELSE
magic. –
Alumna ThisScript.cmd cmd.exe mycmd myarg1 my arg2
? I tried that and nothing happens –
Nabila All you have to do is use the runas
command to run your program as Administrator (with a caveat).
runas /user:Administrator "cmdName parameters"
In my case, this was
runas /user:Administrator "cmd.exe /C %CD%\installer.cmd %CD%"
Note that you must use Quotation marks, else the runas command will gobble up the switch option to cmd.
Also note that the administrative shell (cmd.exe) starts up in the C:\Windows\System32 folder. This isn't what I wanted, but it was easy enough to pass in the current path to my installer, and to reference it using an absolute path.
Caveat: Enable the admin account
Using runas this way requires the administrative account to be enabled, which is not the default on Windows 7 or Vista. However, here is a great tutorial on how to enable it, in three different ways:
I myself enabled it by opening Administrative Tools, Local Security Policy, then navigating to Local Policies\Security Options and changing the value of the Accounts: Administrative Account Status policy to Enabled, which is none of the three ways shown in the link.
An even easier way to accomplish this:
C:> net user Administrator /active:yes
explorer.exe
) is also running as an admin user. (E.g: control.exe
.) However, for my original purpose (seamless installation), Ander's answer is much better suited. –
Avogadro Press the start button. In the search box type "cmd", then press Ctrl+Shift+Enter
A batch/WSH hybrid is able to call ShellExecute to display the UAC elevation dialog...
@if (1==1) @if(1==0) @ELSE
@echo off&SETLOCAL ENABLEEXTENSIONS
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"||(
cscript //E:JScript //nologo "%~f0"
@goto :EOF
)
echo.Performing admin tasks...
REM call foo.exe
@goto :EOF
@end @ELSE
ShA=new ActiveXObject("Shell.Application")
ShA.ShellExecute("cmd.exe","/c \""+WScript.ScriptFullName+"\"","","runas",5);
@end
@REM This is my Script
I get some Microsoft JScript compilation: invalid character
error. If this a batch script, why is this happening? Thanks again. –
Chacon ShA.ShellExecute("cmd.exe","/c \""+WScript.ScriptFullName+"\"","","runas",5);
command. –
Reina @if
-@ELSE
-@end
and >nul...
) that makes this a hybrid. –
Pule @ELSE
is not a JScript keyword because it's uppercase. So everything on lines 2 to 14 are 'IF' statements of outer @if
including inner @if
statement, which has it's 'IF' statements on lines 2 to 11. But because inner @if
condition is false, it would never run lines 2 to 11. If you change @ELSE
to lowercase you will break the whole WSH/batch hybrid. –
Alumna @if
statements and the @ELSE
magic. –
Alumna ThisScript.cmd cmd.exe mycmd myarg1 my arg2
? I tried that and nothing happens –
Nabila @echo off
fsutil dirty query %systemdrive% >nul || (
echo Requesting administrative privileges...
set "ELEVATE_CMDLINE=cd /d "%cd%" & call "%~f0" %*"
findstr "^:::" "%~sf0">"%temp%\getadmin.vbs"
cscript //nologo "%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs" & exit /b
)
rem ------- getadmin.vbs ----------------------------------
::: Set objShell = CreateObject("Shell.Application")
::: Set objWshShell = WScript.CreateObject("WScript.Shell")
::: Set objWshProcessEnv = objWshShell.Environment("PROCESS")
::: strCommandLine = Trim(objWshProcessEnv("ELEVATE_CMDLINE"))
::: objShell.ShellExecute "cmd", "/c " & strCommandLine, "", "runas"
rem -------------------------------------------------------
echo Running script as admin.
echo Script file : %~f0
echo Arguments : %*
echo Working dir : %cd%
echo.
:: administrator commands here
:: e.g., run shell as admin
cmd /k
It also allows passing command line parameters to the batch script.
For a demo: self-elevating.bat "path with spaces" arg2 3 4 "another long argument"
And this is another version that does not require creating a temp file.
@echo off
<!-- : --- self-elevating_no_temp.bat ---------------------
fsutil dirty query %systemdrive% >nul && goto :gotAdmin
echo Requesting administrative privileges...
set "ELEVATE_CMDLINE=cd /d "%cd%" & call "%~f0" %*"
cscript //nologo "%~f0?.wsf" //job:Elevate
exit /b
-->
<job id="Elevate"><script language="VBScript">
Set objShell = CreateObject("Shell.Application")
Set objWshShell = WScript.CreateObject("WScript.Shell")
Set objWshProcessEnv = objWshShell.Environment("PROCESS")
strCommandLine = Trim(objWshProcessEnv("ELEVATE_CMDLINE"))
objShell.ShellExecute "cmd", "/c " & strCommandLine, "", "runas"
</script></job>
:gotAdmin -------------------------------------------------
echo Running script as admin.
echo Script file : %~f0
echo Arguments : %*
echo Working dir : %cd%
echo.
:: administrator commands here
:: e.g., run shell as admin
cmd /k
Edited 11/2023: Corrected the current working directory to "%CD%" instead of "%~dp0" More reliable command to detect if script is run as admin.
cscript "self-elevating.bat?.wsf"
part. –
Progression .bat
and XML .wsh
mix-in content is also gorgeous. –
Progression find "S-1-16-12288"
? It does not appear when I use whoami /groups
. –
Radiotelegraph Although @amr ali's code was great, I had an instance where my bat file contained >
<
signs, and it choked on them for some reason.
I found this instead. Just put it all before your code, and it works perfectly.
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"
echo UAC.ShellExecute "%~s0", "", "", "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"
:--------------------------------------
Simple pipe trick, ||
, with some .vbs used at top of your batch. It will exit regular and restart as administrator.
@AT>NUL||echo set shell=CreateObject("Shell.Application"):shell.ShellExecute "%~dpnx0",,"%CD%", "runas", 1:set shell=nothing>%~n0.vbs&start %~n0.vbs /realtime& timeout 1 /NOBREAK>nul& del /Q %~n0.vbs&cls&exit
It also del /Q
the temp.vbs when it's done using it.
I would set up a shortcut, either to CMD or to the thing you want to run, then set the properties of the shortcut to require admin, and then run the shortcut from your batch file. I haven't tested to confirm it will respect the properties, but I think it's more elegant and doesn't require activating the Administrator account.
Also if you do it as a scheduled task (which can be set up from code) there is an option to run it elevated there.
i just created an shortcut in my desktop with this line in target:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command Start-Process -verb RunAs wt
and after pinned in taskbar :)
You can call PowerShell via its CLI, powershell.exe
, in order to call its Start-Process
cmdlet, which supports starting processes with elevation; doing so has two advantages:
You don't need a hybrid batch file that uses clever, but obscure tricks to combine the languages of two distinct environments in a single file.
You may place
-Wait
before-Verb RunAs
(see below) in order to make the elevated reinvocation synchronous, i.e. to wait for it to exit and communicate its exit code to the caller.
The following borrows techniques from Amr Ali's helpful WSH-assisted answer; save and run as run-elevated.cmd
, for instance:
@echo off & setlocal
:: Check if the current session is already elevated.
:: `net session` only succeeds in elevated sessions.
net session >NUL 2>&1 && goto :ELEVATED
:: Getting here means that we must reinvoke with elevation.
:: Add -Wait before -Verb RunAs to wait for the reinvocation to exit.
set ELEVATE_CMDLINE=cd /d "%~dp0" ^& "%~f0" %*
powershell.exe -noprofile -c Start-Process -Verb RunAs cmd.exe \"/k $env:ELEVATE_CMDLINE\"
exit /b %ERRORLEVEL%
:: Getting here means that we are (now) running with elevation.
:ELEVATED
echo === Running in elevated session:
echo Script file : %~f0
echo Arguments : %*
echo Working dir : %cd%
Speaking of Amr Ali's WSH-assisted answer; here is a reformulation that makes passing the arguments through more robust, so that arguments such as "a & b"
may be passed, and prevents duplicating "^"
characters in arguments by avoiding the use of call
- see line set ELEVATE_CMDLINE=...
; also, apart from some formatting for readability, it is ensured that none of the original batch statements are accidentally echoed:
<!-- : (":" is required)
@echo off & setlocal
net session >NUL 2>&1 && goto :ELEVATED
set ELEVATE_CMDLINE=cd /d "%~dp0" ^& "%~f0" %*
cscript.exe //nologo "%~f0?.wsf" //job:Elevate & exit /b
-->
<job id="Elevate">
<script language="VBScript">
Set objShell = CreateObject("Shell.Application")
Set objWshShell = WScript.CreateObject("WScript.Shell")
Set objWshProcessEnv = objWshShell.Environment("PROCESS")
strCommandLine = Trim(objWshProcessEnv("ELEVATE_CMDLINE"))
objShell.ShellExecute "cmd", "/k " & strCommandLine, "", "runas"
</script>
</job>
:ELEVATED
echo === Running in elevated session:
echo Script file: %~f0
echo Arguments : %*
echo Working dir: %cd%
Browse to C:\windows\System32
and right click on cmd.exe
and run as Administrator. Worked for me on Windows 7.
If you are trying to run a script with elevated privileges you could do the same for the script file or use the scheduler's run as a different user option to run the script.
NirCmd www.nirsoft.net offers elevated Use nircmdc
I personally did not satisfied with any of suggested solutions so I traced and find out how microsoft itself is running some commands as administrator without any confirmations.
Here is what I finally found from windows registry:
*RunAs "D:\Path\To\app.exe"
*RunAs "D:\Path\To\app.exe" [YourCommandArgs]
© 2022 - 2024 — McMap. All rights reserved.
sudo
-like tool for Windows, available as a Chocolatey package: https://mcmap.net/q/89078/-how-to-run-39-sudo-39-command-in-windows-duplicate – Expectation