如何向PowerShell脚本传递JSON文本作为参数?
我要实现的功能很简单:让PowerShell脚本接收JSON文本作为参数,但实际操作远没有那么容易!我查阅了官方关于powershell.exe、解析规则、引号规则的文档,没找到清晰说明,实际情况甚至和文档内容相悖,命令行规则和通用规则并不一致。
我使用PowerShell 5.1,测试脚本test.ps1内容如下:
param($json) Write-Host $json
尝试传递的JSON文本:
{"name" : "value"}
测试过程及结果
测试1:直接传递带双引号的JSON
powershell .\test.ps1 "{"name" : "value"}" # 结果:name : value大括号丢失,双引号被完全移除。
测试2:用反引号转义双引号
powershell .\test.ps1 "{`"name`" : `"value`"}" # 结果:Missing closing '}' in statement block or type definition.反引号未起作用,报错缺少闭合的
}。测试3:双写双引号
powershell .\test.ps1 "{""name"" : ""value""}" # 结果:The string is missing the terminator: ".报错字符串终止符缺失。
测试4:三写双引号
powershell .\test.ps1 "{"""name""" : """value"""}" # 结果:Unexpected token ':' in expression or statement.报错存在意外令牌
:。测试5:用单引号包裹JSON
powershell .\test.ps1 '{"name" : "value"}' # 结果:{name : value}保留了大括号,但双引号丢失。
测试6:单引号内用反引号转义双引号
powershell .\test.ps1 '{`"name`" : `"value`"}' # 结果:{`name` : `value`}双引号仍被移除,反引号被保留。
测试7:单引号内双写双引号
powershell .\test.ps1 '{""name"" : ""value""}' # 结果:{name : value}双引号依旧丢失。
测试8:单引号内三写双引号
powershell .\test.ps1 '{"""name""" : """value"""}' # 结果:{"name" : "value"}此方法成功,但写法繁琐,多层嵌套JSON时需要更多引号,极不方便。用
-EncodedCommand参数也不是简便方案。
原理解析与最优方案(更新)
命令行参数首先由CMD shell处理,CMD用双引号处理含空格的参数,之后PowerShell会移除成对的双引号,且PowerShell将\视为转义字符,核心规则:
- 参数首尾的引号会被无条件移除
- 可以用
\转义内部的引号
修正后的可行命令
用PowerShell单引号包裹转义后的JSON:
powershell .\test.ps1 "'{\\"name\\" : \\"value\\"}'" # 结果:{"name" : "value"}此时传递到powershell.exe的字符串是
{"name" : "value"},通过单引号包裹避免PowerShell将其解析为无效语法。最优方案:使用
-File参数
当使用-File参数时,PowerShell不会将参数解析为PowerShell代码,直接传递给脚本:powershell -File .\test.ps1 "{\\"name\\" : \\"value\\"}" # 结果:{"name" : "value"}
内容的提问来源于stack exchange,提问作者Alsin

