1

Double quotes structure is not retained in my test message when passed through a powershell instance called through a batch script, as detailed below:

set test={"this":"is","a":"test"}
FOR /F "delims=" %%i in (' powershell -Command "& {$message = '%test%'; echo $message}" ') DO SET message=%%i
echo %test%
echo %message%

the output is as follows:

{"this":"is","a":"test"}
{this:is,a:test}

I would like to retain the quotes to further process the string in powershell, but as you can see, they are stripped when introduced into the $message variable.

Any insight as to how I might fix this?

cal
  • 23
  • 4
  • 1
    To escape double quotes in a batch command, you need to use *double* double quotes: `set test={""this"":"is"",""a"":""test""}`, see also: https://stackoverflow.com/a/15262019/1701026 – iRon Apr 25 '19 at 18:33
  • 1
    @iRon Sadly I attempted this already with these results: `{""this"":""is"",""a"":""test""} {"this:is,a:test}` The latter being the output from powershell. Only the first doublequote escapes, but not anything else. – cal Apr 25 '19 at 18:47
  • @iRon: It is PowerShell that is called from the batch file, so you must satisfy _PowerShell's_ escaping requirements re embedded double quotes - and that means escaping them as `\"` when calling the CLI (perhaps surprisingly, given that PowerShell-_internally_ it is `\`"` or `""`). – mklement0 Apr 25 '19 at 19:07

1 Answers1

5

Echoing %test% containing double quotes inside the d-quoted powershell command will break the enclosing d-quotes.

One way to overcome this, is using batch string substitution to escape the inner d-quotes with a backslash on the fly

:: Q:\Test\2019\04\25\SO_55855412.cmd
@Echo off
set "test={"this":"is","a":"test"}"
FOR /F "delims=" %%i in ('
     powershell -Command "& {$message = '%test:"=\"%'; echo $message}" 
') DO SET "message=%%i"
echo %test%
echo %message%

returns here:

> SO_55855412.cmd
{"this":"is","a":"test"}
{"this":"is","a":"test"}

Another solution is to NOT pass %test% as an argument, but to get the variable from the inherited environment

    powershell -Command "& {$message = $env:test; echo $message}"

Sadly this doesn't work to pass a variable back, as on terminating the spawned app the inherited environment is discarded.