I spent some time figuring out the correct syntax for a Powershell script. However in the end it was trial and error approach and I would like to know why the syntax below doesn't work.
The script starts new Powershel in elevated mode and sets environment variable. Here's the excerpt:
$x = "NewValue"
$arguments = "-NoExit", "-command", "&{ [Environment]::SetEnvironmentVariable(`"MyVar1`", `"$x`", [EnvironmentVariableTarget]::Machine) }"
Start-Process powershell -Verb runAs -ArgumentList $arguments
If I just print out the variable $arguments, it's an array as I would expect:
-NoExit
-command
&{ [Environment]::SetEnvironmentVariable("MyVar1", "NewValue", [EnvironmentVariableTarget]::Machine) }
However, in the child Powershell the double quotes are eaten somehow and missing. Why? Is it expected behavior? It outputs:
At line:1 char:42
+ &{ [Environment]::SetEnvironmentVariable(MyVar1, NewValue, [EnvironmentVariableT ...
+ ~
Missing ')' in method call.
At line:1 char:42
+ &{ [Environment]::SetEnvironmentVariable(MyVar1, NewValue, [EnvironmentVariableT ...
+ ~~~~~~
Unexpected token 'MyVar1' in expression or statement.
At line:1 char:48
+ &{ [Environment]::SetEnvironmentVariable(MyVar1, NewValue, [EnvironmentVariableT ...
+ ~
Missing argument in parameter list.
At line:1 char:2
+ &{ [Environment]::SetEnvironmentVariable(MyVar1, NewValue, [EnvironmentVariableT ...
+ ~
Missing closing '}' in statement block.
At line:1 char:96
+ ... arget]::Machine) }
+ ~
Unexpected token ')' in expression or statement.
At line:1 char:98
+ ... get]::Machine) }
+ ~
Unexpected token '}' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
My environment:
> $PSVersionTable
Name Value
---- -----
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.42000
BuildVersion 6.3.9600.17400
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
===============================================================
For reference, here's working version using single quotes instead of double quotes (I also removed -NoExit parameter, which was there only for debugging):
$x = "NewValue"
$arguments = "-command", "&{ [Environment]::SetEnvironmentVariable('MyVar1', `'$x`', [EnvironmentVariableTarget]::Machine) }"
Start-Process powershell -Verb runAs -ArgumentList $arguments
It is how PowerShell.exe parse its command line. It mostly follows .NET rules of command line parsing:
Space is an argument separator. PowerShell.exe will join individual arguments by single space regardless of how many spaces you use to separate arguments.
CMD> PowerShell -Command echo 'multiple spaces'
multiple spaces
If you want to include space in argument value, then you should enclose space in double quotes. Double quotes itself are not a part of resulting argument value and can be anywhere inside argument:
CMD> PowerShell -Command echo 'mult"iple spa"ces'
multiple spaces
If you want literal double quote to be part of argument value, then you have to escape it with backslash:
CMD> PowerShell -Command echo 'literal\"double\"quotes'
literal"double"quotes
If you want literal backslash to precede double quote, then you have to escape that backslash with another backslash. Other than that, backslash interpreted literally and does not need to be escaped:
CMD> PowerShell -Command echo 'back\\slash\\" something\\else\\"'
back\\slash\ something\\else\
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With