Search code examples
powershellescapingdouble-quotes

A PowerShell command executed through runas.exe


I need to execute the PS command through runas.exe. The PS command works separately, but I can't make it work as a runas.exe call. Seems to be an escaping issue, but quotes + double-quotes don't work here for some reason :(

The original command:

runas.exe /savecred /user:user "cmd.exe /k powershell -Command "& {echo 123}""

Thanks!


Solution

  • :: From cmd.exe
    runas.exe /savecred /user:user "powershell -NoExit -Command \"^& { echo 123 }\""
    
    • There is no need to call via cmd /k - passing -NoExit to powershell.exe directly keeps the session open.

    • The embedded " inside your overall "..." string must be escaped, as \"

      • Unfortunately, because cmd.exe itself - unlike runas.exe - doesn't recognize \" as an escaped " and therefore considers it a closing " for the outer starting ", as a result of which it considers the & to be outside "...", which would cause interpretation as cmd.exe's statement-sequencing operator. Escaping & as ^& avoids that.
        Note that other cmd.exe metacharacters, such as |, would have to be ^-escaped too.

    You can avoid or lessen the need for ^-escaping by taking advantage of the fact that powershell.exe, the Windows PowerShell CLI, also allows you to pass the components of a command string as individual arguments, i.e. without overall "..." enclosure:

    :: From cmd.exe. 
    :: No embedded "..." enclosure for the -Command arguments -> no need to ^-escape &
    runas.exe /savecred /user:user "powershell -NoExit -Command & { echo 123 }"
    

    Further, note that you don't need & { ... } around a command you pass to -Command - just use the command directly:

    :: From cmd.exe. 
    :: No need for & { ... }
    runas.exe /savecred /user:user "powershell -NoExit -Command echo 123"
    

    All that said, you can still run afoul of cmd.exe's parsing, namely when the PowerShell command itself requires " characters (as opposed to using " merely syntactically for the initial command line):

    The following makes PowerShell print verbatim 3" of snow & more:

    runas.exe /savecred /user:tu1 "powershell -NoExit -Command echo '3\\\" of snow ^& more'"
    

    Note the need to doubly escape the " character (\\\", to first escape for runas.exe, and then for powershell.exe), and again the need to ^-escape & for the benefit of cmd.exe.