I have a PowerShell script that edits the registry, so it needs to be run as admin. To do this, I start a new PowerShell process from my PowerShell script run and pass part of the registry key path using a script block with a function in it. When I use double quotes inside this function, PowerShell tries to interpret them as commands, not a string. If I use single quotes, then everything works fine.
I created a small truncated powershell script model that reproduces the problem. Here is a snippet:
$ScriptBlock = { function Test { $status = "This is a string" Write-Output $status } } Start-Process -FilePath PowerShell -ArgumentList "-NoExit -NoProfile -ExecutionPolicy Bypass -Command & {$ScriptBlock Test}"
So, in the new PowerShell process, it will first determine the code in the script block, and then call the Test method and produce this error:
This: the term 'This' is not recognized as a cmdlet name, function, script file, or operating program. Check the spelling of the name, or if the path was included, make sure the path is correct and try again.
Therefore, it tries to treat the string as a combat, as if I just typed This is a string myself on a new line in the script.
If I changed the line
$status = "This is a string"
to
$status = 'This is a string'
The script works as expected and simply prints the string This is a string .
Another weird problem I noticed is that if I don't use a variable and just use:
Write-Output "This is a string"
then it displays each word on a separate line as follows:
it
is an
a
line
but if I use single quotes as follows:
Write-Output 'This is a string'
then it displays the whole sentence on one line, as expected.
Does anyone know why PowerShell behaves strangely in these situations?
Answer
So, as TessellatingHeckler mentions, the solution does carry over everything that is double quoted in double double quotes, single quotes, or you can use parentheses.
So, in my example, you would change:
$status = "This is a string"
:
$status = """This is a string"""
or that:
$status = '"This is a string"'
or that:
$status = {"This is a string"}
If you want to evaluate the variable in your string, though (for example, see the value of the variable), you need to go with the double double quote method:
$status = """This is a string that evaluates $someVariable"""
Not sure if this is a design error, but at least we have a workaround as it fixes both of the problems described above.