Question

PowerShell wont work as admin with double quotes

The problem is that the '-Verb RunAs' wont work with '\"' for some reason and I need the quotes for better handeling of paths

:: Check for admin privilage
openfiles > nul 2>&1
if !errorlevel! neq 0 (
    echo | set /p="The execution needs elevated privileges (y|n)"
    choice /n
    if !errorlevel! equ 1 (
        start /b /wait PowerShell -Command "Start-Process '%~f0' -ArgumentList '%res% -ico \"%icon%\" -dir \"%directory%\"' %style% -Verb RunAs"
        exit /b
    )
)

when I remove one of them the other works

::like this
start /b /wait PowerShell -Command "Start-Process '%~f0' -ArgumentList '%res% -ico \"%icon%\" -dir \"%directory%\"' %style%"

::or this
start /b /wait PowerShell -Command "Start-Process '%~f0' -ArgumentList '%res% -ico %icon% -dir %directory%' %style% -Verb RunAs"

Or when I convert it into an executable it works

I don't know why is that happening maybe a glitch or something I hope someone finds a solution

 3  104  3
1 Jan 1970

Solution

 3

To spell it out: You're trying to create a self-elevating batch file, i.e. one that reinvokes itself with elevated (administrative) privileges while passing arguments through.

You appear to have hit a bug where reinvoking a batch file with arguments that are enclosed in "..." syntactically breaks the invocation of the target process when elevation is requested via PowerShell's Start-Process -Verb RunAs. I don't know for sure, but I suspect that the bug is at a level below PowerShell.

The workaround is to call the batch file via cmd.exe /C and to enclose the entire argument list passed to the latter in "..." overall, in addition to the "..." enclosure of individual arguments

  • To provide a simple example: the process command line that must ultimately be launched has to look something like this - note the - unescaped - outer "..." that encloses the double-quoted batch-file path and all pass-through arguments, which may be individually double-quoted:

    "C:\Windows\System32\cmd.exe" /c ""c:\path\to\my.cmd" -foo "bar""
    

Here's a self-contained, streamlined demonstration of the workaround, incorporating incidental improvements suggested by Compo.

@echo off & setlocal enabledelayedexpansion

:: ...

:: Check for admin privileges
net sessions > nul 2>&1 || (
  choice /m "The execution needs elevated privileges"
  if !errorlevel! equ 1 (
        echo Relaunching with elevation and arguments and waiting for completion...
        start /b /wait "" PowerShell -NoProfile -Command "Start-Process -Wait -Verb RunAs cmd.exe -ArgumentList '/C \"\"%~f0\" %res% -ico \"%icon%\" -dir \"%directory%\"\"' %style%"
        exit /b
  ) else (
        echo Elevation request declined. >&2
        exit /b 1
  )
)

:: Getting here means that the batch file runs elevated.

echo Running elevated; args given: [%*]

pause
2024-07-11
mklement0