powershellbatch-filecmdcommand-line-argumentspowershell-5.0

Pass argument(file-path) that contains spaces to the Powershell command inside Batch file that itself resides at path with spaces


I have following lines in my Batch script which in turn calls Powershell command to self-elevate the batch file as Admin.

@echo off && setlocal
if not "%1"=="admin" (powershell start -verb runas '%0' admin & pause & exit /b)
....
....

But the Batch file path itself and as result the '%0' contains spaces in the %USERNAME%(Vivek Shah) especially, and that's why when invoking this script, it throws error:

The term 'C:\Users\Vivek' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
again.
At line:1 char:1

How do I handle spaces in '%0' and make this script working perfectly ??

Already tried '%~0' & '"%0"' but both apparently don't work.


Solution

  • @echo off && setlocal
    
    if not "%1"=="admin" (powershell start -verb runas \"%~f0\" admin & pause & exit /b)
    

    [1] Note: Without enclosing the implied -Command argument in "..." overall means that the value of ~%f0 is subject to whitespace normalization, meaning that runs of multiple whitespace characters are folded into a single space each. However, that is rarely a problem in practice. Just adding an overall "..." enclosure (powershell "start ..." & pause & exit /b) is not necessarily enough, unfortunately, because it requires individually ^-escaping any cmd.exe metacharacters inside \"...\". In the rare event that whitespace normalization is a problem, with powershell.exe you can use "^""..."^"" (sic) inside overall "...", but only outside for /f loops - see this answer. Fortunately, in PowerShell (Core) 7+, whose CLI is pwsh.exe, the robust solution is simpler: both outside and inside for /f, use overall "..." enclosure with embedded ""..."" quoting.