powershellbatch-filecmdescapingquoting

Running a Powershell Start-Process command, with arguments containing spaces, from a batch script


I can't get this batch script to work, even though I tried a lot of things, I'm now stuck.

The intention is for the batch script to re-run itself elevated, using PowerShell and Start-Process, if the admin check fails.

As long as the passed argument(s), do not contain spaces it works fine. However I need to forward the original batch arguments, (file paths), and can't figure out how to handle the case where they contain spaces.

Here is a small example of what I'm trying to achieve, in this example the echo doesn't correctly print out Arg 1 and Arg 2:

@echo off
setlocal enabledelayedexpansion

echo %1
echo %2

net session >nul 2>&1
if %ERRORLEVEL% neq 0 (
    echo Need to fix association but missing admin rights...
    echo Elevating privileges...

    REM Once it work, 'Arg 1' and 'Arg 2' will be replaced by %1 and %2 
    REM Which are gonna be path enclosed with double quote and containing space ie : "C:\Path to\A folder\"
    powershell -Command "$args = 'Arg 1', 'Arg 2'; Start-Process -Verb RunAs -FilePath '%~dpnx0' -ArgumentList $args"
    pause
    exit /b
)

pause
endlocal

Solution

  • There are multiple challenges:

    Therefore, use the following (note that I'm omitting enabledelayedexpansion, as it isn't necessary here, and can cause problems with what should be verbatim ! characters):

    @echo off
    setlocal
    
    net session >nul 2>&1 || (
        echo Need to fix association but missing admin rights...
        echo Elevating privileges...
    
        powershell -noprofile -Command $argStr = '\"%~1\" \"%~2\"'; Start-Process -Verb RunAs cmd.exe '/c', \"`\"`\"%~f0`\" $argStr`\"\"
        pause
        exit /b
    )
    
    echo Now running with elevation; arguments received:
    echo [%1]
    echo [%2]
    
    pause
    endlocal
    

    Note: