I have a PowerShell script that edits the registry, so it needs to run as admin. To do this, I start up a new PowerShell process from my running PowerShell script, and pass in part of the registry key path using a Script Block with a function in it. When I use double quotes within that function, PowerShell tries to interpret them as commands, rather than a string. If I use single quotes though, then everything works fine.
I've created a little stripped down sample powershell script that reproduces the problem. Here's the 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 define the code in the script block and then call the Test method, and it produces this error:
This : The term 'This' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
So it's trying to treat the string as a commad, as if I had just typed This is a string
by itself on a new line in my script.
If I change the line
$status = "This is a string"
to
$status = 'This is a string'
the script works as expected and simply outputs the string This is a string
.
Another strange problem I've noticed is that if I don't use a variable and just use:
Write-Output "This is a string"
then it outputs each word on a separate line like this:
This
is
a
string
but if I use single quotes like this:
Write-Output 'This is a string'
then it outputs the entire sentence on one line as expected.
Does anybody know why PowerShell is behaving strangely in these situations?
Answer
So as TessellatingHeckler mentions, the solution is do wrap anything that is double quoted in double double quotes, single quotes, or you can use brackets.
So in my example, you would change:
$status = "This is a string"
to this:
$status = """This is a string"""
or this:
$status = '"This is a string"'
or this:
$status = {"This is a string"}
If you want to evaluate a variable in your string though (i.e. see the variable's value), then you have to go with the double double quotes method:
$status = """This is a string that evaluates $someVariable"""
Still not sure if this is a Bug or By Design, but at least we have a workaround, as this fixes both of the problems I described above.