Everyone need to escape their PowerShell sometimesDavid Moss 2022
especially if a string contains $ or “
PowerShell has a special construct for multi-line strings called the here-string
$thing = @" $greeting = "Hello World" write-output ($greeting) "@
Above a variable ($thing) is declared and initialised with a multi-line String.
Note the first thing after the = sign is an @ character followed by a double-quote character.
Also note there is nothing else on that line.
The here-string continues across multiple lines and can contain any character sequence, even quote characters.
The here-string is terminated by a double-quote character followed by an @ character on a line by themselves.
The here-string is very useful but it can be tricky. After entering the above in a script, running the command:
= "Hello World" write-output ()
which is not what most people expect. Even worse, trying to use the here-string to construct a scriptblock results in a nasty error:
Invoke-Command -ScriptBlock ([ScriptBlock]::Create($thing))
Line | 8 | Invoke-Command -ScriptBlock ([ScriptBlock]::Create($thing)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Exception calling "Create" with "1" argument(s): "At line:2 char:15 + write-output (); + ~ An expression was expected after '('."
Now that is an obscure error! It is caused by not ‘escaping’ the special characters in the here-string properly.
The escape character in PowerShell is the grave character, `. That is not a flyspeck before the full stop character in the last sentence. It is the grave character, or ‘back-tick’, often found around the top left of the keyboard. On the Mac keyboard it shared a key with the tilde character, ~. Lets try again with escaping:
$thing = @" `$item = `"hi there`"; write-output (`$item); "@ Write-Output ($thing) Invoke-Command -ScriptBlock ([ScriptBlock]::Create($thing))
which results in:
$item = "hi there"; write-output ($item); hi there
I have escaped the $ character and the ” characters inside the here-string with the ` character.