6

Placing the following within a script will fail:

$MyString = @'
hello
@'
'@
bye
'@

write-host $MyString

The error returned is as follows:

At C:\scripts\test.ps1:6 char:1
+ '@
+ ~~
The string is missing the terminator: '.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

Prefixing the nested @' and '@ with a backtick (grave accent) does serve as an escape character, however it is also treated as literal, and therefore appears in the output of $MyString.

Is there a correct way to escape a single quoted here-string within a single quoted here-string that does not interfere with the output?

NB:

I should have mentioned that the content of the outer here-string is dynamically populated, the content is supplied by another program to the powershell script as a command line argument. This is not reflected in the sample code as I didn't want to cloud the question with my very specific and somewhat niche implementation.

It's not all that likely that the outer here-string will contain an inner here-string (but it could happen), therefore I feel that some defensive programming is warranted in order to accommodate such an occurrence.

3 Answers 3

4

Use double quotes, either for the outer here-string:

$MyString = @"
hello
@'
'@
bye
"@

or for the inner here-string:

$MyString = @'
hello
@"
"@
bye
'@
Sign up to request clarification or add additional context in comments.

6 Comments

I use a single quoted here-sting in my script because it may contain HTML. If I use double quotes then javascript function calls would be misinterpreted as PowerShell sub-expressions and thus expanded.
Then use double quotes for the inner here-string.
I have no control over the input supplied. An external process calls the powershell script, supplying the content of the here-string as an argument.
Please update your question with a complete description of your problem. We're not playing 20 Questions here.
Please accept my apology - I do have control over the content within the outer here-string. Otherwise how would I escape it?? Changing the inner here-string to use double quotes I will accept it. That appears to be the cleanest way of updating the content with
|
2

Try a ScriptBlock (enclosed in {}) instead of the outer Here-String. It works for the original example:

$MyString = {
hello
@'
'@
bye
}
write-host $MyString

Result:

PS > $MyString = {
>> hello
>> @'
>> '@
>> bye
>> }
>> write-host $MyString
>>

hello
@'
'@
bye

PS >

Note the extra blank lines at the beginning and the end. You can avoid them if you omit the line breaks after { and before }.

You may explicitly convert the ScriptBlock to a String with the ToString() function, if necessary.

Not sure if this workaround works in any use case, but it looks fairly clean, because the ScriptBlock takes all content without interpretation and is not confused by any curly braces nor is it interested in any quotes.

Comments

1

Regardless of whatever here-string quote character you choose, there is always the powershell escape character, the backtick

$MyString = @"
hello
@`'
`'@
bye
"@

is equivalent to

$MyString = @'
hello
@`'
`'@
bye
'@

If you need to esccape a backtick, just put 2 of them

Write-Host @"

here is a backtick ``

"@

Comments

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.