Based on How can I auto-elevate my batch file, so that it requests from UAC administrator rights if required? I'm trying to make an RunElevated.bat
(see code below) that accepts a command-line (batch file name and parameters) as arguments.
The RunElevated.bat
works fine when the target batch file path has no spaces in them. But it fails as soon as that path has spaces: no matter how I quote things, either PowerShell barfs, or the parameters are not passed correctly from PowerShell to the batch file.
I tried:
- escaping with
""
(as suggested by many sources) - escaping with
\"
(as suggested by Escaping quotes in powershell.exe -command via command prompt) - adding
--%
(as suggested by PowerShell and external commands done right and Easier Reuse of Command Lines From Cmd.exe) surrounding with
'
(as suggested by CB.). So:- Is what I want to do possible at all?
- If so: how?
RunElevated.bat
:
:checkParameters
echo [%*]
if [%1]==[] ( goto :help ) else ( goto :checkPrivileges )
:help
echo Syntax:
echo %0 CmdLine
echo Where CmdLine is executed with UAC privileges.
goto :exit
:checkPrivileges
net file 1>nul 2>nul
if '%errorlevel%' == '0' ( goto :gotPrivileges ) else ( goto :getPrivileges )
:getPrivileges
PowerShell "Start-Process -FilePath \"%0\" -Verb RunAs -ArgumentList \"%*\""
goto :exit
:gotPrivileges
%*
pause
:exit
pause
exit /b
echo-cd.bat
which I stored in both D:\tools\echo-cd.bat
and "D:\to ols\echo-cd.bat"
:
echo Current Directory: [%CD%]
echo Parameters: [%*]
pause
This runs fine:
D:\tools\RunElevated.bat D:\tools\echo-cd.bat foo
These fail:
D:\tools\RunElevated.bat "D:\to ols\echo-cd.bat" foo
First failure is at the %*
:
C:\Windows\system32>D:\to ols\echo-cd.bat foo
'D:\to' is not recognized as an internal or external command,
operable program or batch file.
This is because PowerShell removed the quotes around the batch file name:
C:\Windows\system32>echo [D:\to ols\echo-cd.bat foo]
[D:\to ols\echo-cd.bat foo]
I expected D:\to ols\echo-cd.bat
to have double quotes around it, and foo
not.
D:\tools\RunElevated.bat \"D:\to ols\echo-cd.bat\" foo
Second failure is at the PowerShell
level:
D:\>PowerShell "Start-Process -FilePath \"D:\tools\RunElevated.bat\" -Verb RunAs -ArgumentList \"\"D:\to ols\echo-cd.bat\" foo\""
Start-Process : Cannot validate argument on parameter 'ArgumentList'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
At line:1 char:77
+ Start-Process -FilePath "D:\tools\RunElevated.bat" -Verb RunAs -ArgumentList <<<< ""D:\to ols\echo-cd.bat" foo"
This is because escaping twice will end up with an empty string for ArgumentList
.
D:\tools\RunElevated.bat --% "D:\to ols\echo-cd.bat" foo
Third failure is also at the %*
:
C:\Windows\system32>--% D:\to ols\echo-cd.bat foo
'--%' is not recognized as an internal or external command,
operable program or batch file.
This too is because PowerShell removed the quotes around the batch file name:
C:\Windows\system32>echo [--% D:\to ols\echo-cd.bat foo]
[--% D:\to ols\echo-cd.bat foo]
I expected --%
to be absent, D:\to ols\echo-cd.bat
to have double quotes around it, and foo
not.
D:\tools\RunElevated.bat '"D:\to ols\echo-cd.bat"' foo
Again a failure is at the %*
:
C:\Windows\system32>'D:\to ols\echo-cd.bat' foo
The filename, directory name, or volume label syntax is incorrect.
This is because PowerShell removed the double quotes (and left the single quotes) around the batch file name:
C:\Windows\system32>echo ['D:\to ols\echo-cd.bat' foo]
['D:\to ols\echo-cd.bat' foo]
C:\Windows\system32>if ['D:\to] == [] (goto :help ) else (goto :checkPrivileges )