1

Look at this cmd.exe command: powershell.exe -NonInteractive -NoProfile -Command "&(""{0}{1}""-f 'ec','ho') hello" powershell reports error:

C:\Users\Administrator>powershell.exe -NonInteractive -NoProfile -Command "&(""{0}{1}""-f 'ec','ho') hello"
The string is missing the terminator: ".
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

Seems that a " terminator is missing? But wrote a C program that outputs argv line by line, to see what the arguments really expanded to:

#include <iostream>

using namespace std;

int wmain(int argc, wchar_t* argv[])
{
    for (int i = 0; i < argc; i++) {
        wcout << i << L":" << argv[i] << endl;
    }
}
C:\Users\Administrator\source\repos\ArgvDemo\x64\Debug>.\ArgvDemo.exe powershell.exe -NonInteractive -NoProfile -Command "&(""{0}{1}""-f 'ec','ho') hello"
0:.\ArgvDemo.exe
1:powershell.exe
2:-NonInteractive
3:-NoProfile
4:-Command
5:&("{0}{1}"-f 'ec','ho') hello

The last argument parsed just fine!
And the powershell command &("{0}{1}"-f 'ec','ho') hello runs fine:

PS C:\Users\Administrator> &("{0}{1}"-f 'ec','ho') hello
hello

And actually if I add an extra " to the command in question:

powershell.exe -NonInteractive -NoProfile -Command "&(""{0}{1}""-f 'ec','ho') hello"
                                                  Add " here   ^
powershell.exe -NonInteractive -NoProfile -Command "&(""{0}{1}"""-f 'ec','ho') hello"

It runs fine:

C:\Users\Administrator\source\repos\ArgvDemo\x64\Debug>powershell.exe -NonInteractive -NoProfile -Command "&(""{0}{1}"""-f 'ec','ho') hello"
hello

But if I put it in my C program:

C:\Users\Administrator\source\repos\ArgvDemo\x64\Debug>.\ArgvDemo.exe powershell.exe -NonInteractive -NoProfile -Command "&(""{0}{1}"""-f 'ec','ho') hello"
0:.\ArgvDemo.exe
1:powershell.exe
2:-NonInteractive
3:-NoProfile
4:-Command
5:&("{0}{1}"-f
6:'ec','ho')
7:hello

What happened?

What I understand is that double quote "" inside a pair of quote " will be parsed to a single quote: "arg: ""quote""!" = arg: "quote"!. But is it really the case?

2 Answers 2

2

Preface:

  • I am addressing the question as asked, namely how to escape embedded " chars., i.e. double quotes.

    • Situationally, if you're dealing with string values to used verbatim (literally), it is easier to use embedded ', i.e. single quotes, which doesn't require any escaping, as shown in Alex' answer.

    • However, if you do need string interpolation in your PowerShell code or you're passing a file path that may contain spaces via an (environment) variable, "..." quoting is called for.

  • See the about_Quoting_Rules help topic for the differences between "..." (expandable) and '...' (verbatim) strings in PowerShell.


Using "" to escape double quotes embedded in an overall "..."-enclosed -Command PowerShell CLI argument only works in PowerShell (Core) 7, i.e. only with pwsh.exe

In Windows PowerShell (the legacy, ships-with-Windows, Windows-only edition of PowerShell whose latest and last version is 5.1), whose CLI is powershell.exe, you must use \" or """ [sic]; applied to your command, using \":

powershell.exe -NoProfile -Command "& (\"{0}{1}\"-f 'ec','ho') hello"

Note that both forms of escaping can run afoul of cmd.exe's own up-front parsing, because cmd.exe doesn't itself recognize escaped " chars.; e.g.:

:: FAILS, because cmd.exe sees the & char. as UNESCAPED and therefore as its
:: statement sequencing operator.
powershell.exe -NonInteractive -NoProfile -Command " \"hi & bye\" "

:: DITTO
powershell.exe -NonInteractive -NoProfile -Command " """hi & bye""" "

To prevent that, use \"" [sic] (subject to whitespace normalization) or "^"" [sic] (preserves whitespace, but doesn't work in for /f statements):

:: With \""
:: OK, but normalizes whitespace
powershell.exe -NonInteractive -NoProfile -Command " \""hi   &   bye\"" "

:: With "^""
:: OK, but doesn't work with `for /f`
powershell.exe -NonInteractive -NoProfile -Command " "^""hi   &   bye"^"" "
  • For more information, see this answer.

  • In PowerShell (Core) 7 (which supports \"-escaping too), escaping as "" works robustly in all scenarios (on Windows).

Sign up to request clarification or add additional context in comments.

Comments

0

Try this, issue stems from the quotes:

powershell.exe -NonInteractive -NoProfile -Command "& (('{0}{1}' -f 'ec','ho'))" hello

2 Comments

You're missing hello at the end of the command.
it's right there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.