script - powershell tutorial
Powershell-cadena de escape pasada al proceso hijo (1)
Es cómo
PowerShell.exe
analiza su línea de comando.
En su mayoría sigue las
reglas de .NET de análisis de línea de comandos
:
-
El espacio es un separador de argumentos.
PowerShell.exe
unirá argumentos individuales por un solo espacio, independientemente de cuántos espacios use para separar los argumentos.CMD> PowerShell -Command echo ''multiple spaces'' multiple spaces
-
Si desea incluir espacio en el valor del argumento, debe encerrarlo entre comillas dobles. Las comillas dobles en sí mismas no son parte del valor del argumento resultante y pueden estar en cualquier lugar dentro del argumento:
CMD> PowerShell -Command echo ''mult"iple spa"ces'' multiple spaces
-
Si desea que la doble comilla literal sea parte del valor del argumento, debe escapar con una barra diagonal inversa:
CMD> PowerShell -Command echo ''literal/"double/"quotes'' literal"double"quotes
-
Si desea que la barra diagonal inversa preceda a la comilla doble, debe escapar de esa barra diagonal inversa con otra barra diagonal inversa. Aparte de eso, la barra invertida se interpreta literalmente y no necesita escapar:
CMD> PowerShell -Command echo ''back//slash//" something//else//"'' back//slash/ something//else/
Pasé un tiempo descubriendo la sintaxis correcta para un script de Powershell. Sin embargo, al final fue un enfoque de prueba y error y me gustaría saber por qué la sintaxis a continuación no funciona.
El script inicia un nuevo Powershel en modo elevado y establece una variable de entorno. Aquí está el extracto:
$x = "NewValue"
$arguments = "-NoExit", "-command", "&{ [Environment]::SetEnvironmentVariable(`"MyVar1`", `"$x`", [EnvironmentVariableTarget]::Machine) }"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Si solo imprimo la variable
$arguments
, es una matriz como esperaría:
-NoExit
-command
&{ [Environment]::SetEnvironmentVariable("MyVar1", "NewValue", [EnvironmentVariableTarget]::Machine) }
Sin embargo, en el Powershell hijo, las comillas dobles se comen de alguna manera y faltan. ¿Por qué? ¿Es el comportamiento esperado? Produce:
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
Mi entorno:
> $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
================================================== =============
Como referencia, aquí está la versión que funciona con comillas simples en lugar de comillas dobles (también eliminé el parámetro -NoExit, que solo estaba allí para la depuración):
$x = "NewValue"
$arguments = "-command", "&{ [Environment]::SetEnvironmentVariable(''MyVar1'', `''$x`'', [EnvironmentVariableTarget]::Machine) }"
Start-Process powershell -Verb runAs -ArgumentList $arguments