如何将JSON(字符串数据)传递到PowerShell? [英] How to pass JSON (string data) to PowerShell?
问题描述
我将以下内容作为参数传递给powershell(w7上的v4):
I'm passing the following as an argument to powershell (v4 on w7):
-debugWrite -fileName SettingsFile -jsonContent { "c": "some setting", "d": "unknown", "b": "some thing", "a": 1 }
但是PS挂在了JSON上.我尝试定界\ double-quotes \并将所有内容放在-jsonContent之后的单引号"中,但无济于事.
But PS gets hung up on the JSON. I've tried delimiting the \double-quotes\ and putting everything after -jsonContent in 'single quotes', but to no avail.
这是PS在其中运行的Windows 7(PS4)环境:
Here is the Windows 7 (PS4) environment PS is running in:
注意:"..."混淆指的是相同的目录. IOW,所有文件都位于同一目录中.
批处理文件运行,开始整个过程:
A batch file is run, kicking off the whole thing:
"C:\...\script.bat" > "C:\...\script-output.txt" 2>&1
这将运行script.bat
并输出到script-output.txt
. script.bat
是长1线:
This runs script.bat
and outputs to script-output.txt
. script.bat
is a long 1-liner:
%WINDIR%\sysnative\windowspowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -File "C:\...\customscript.PS1" --% -fileName DropFileToCreate -jsonContent "{ "c": "some setting", "d": "unknown", "b": "some thing", "a": 1 }" -debugWrite
传奇:
DropFileToCreate
-传递给PS脚本的文件名,用于在同一目录中创建文件.
DropFileToCreate
- the filename passed to the PS script, used to create a file in same dir.
-jsonContent
-脚本中的命名参数(请参见下面的customscript.PS1
标头)
-jsonContent
- A named parameter in the script (see below for header of customscript.PS1
)
在上面的示例中,JSON为:
In the above example, the JSON is:
" {"c":某些设置","d":未知","b":一些 事物",一个":1}"
"{ "c": "some setting", "d": "unknown", "b": "some thing", "a": 1 }"
-debugWrite
-开关参数(用于启用写入主机调试)
-debugWrite
- A switch parameter (used here to enable Write-Host debugging)
最后,是customscript.PS1
的一部分:
Param (
[Parameter(Mandatory = $True)]
[String]
$fileName,
[Parameter(Mandatory = $True)]
$jsonContent,
[Parameter(Mandatory = $False)]
[Switch]
$debugWrite = $False
)
[...]
如果表示为JSON,则更容易看到JSON,并解释了空格
The JSON is easier seen, and spaces explained, if expressed as:
{
"c": "some setting",
"d": "unknown",
"b": "some thing",
"a": 1
}
推荐答案
tl; dr
您的整个"..."
封闭的JSON字符串已嵌入 "
,必须将其转义为\"
(原文为sic;简化了命令):
Your overall "..."
-enclosed JSON string has embedded "
, which must be escaped as \"
(sic; command simplified):
powershell.exe -File "C:\...\customscript.PS1" ... -jsonContent "{ \"c\": \"some setting\", \"d\": \"unknown\", \"b\": \"some thing\", \"a\": 1 }"
请继续阅读,了解何时需要进行其他转义,-File
调用与-Command
调用有何不同,以及调用外壳程序(在其中调用powershell.exe
的位置)的重要性.
Read on for when additional escaping is needed, how -File
invocation differs from -Command
invocation, and in what way the calling shell (where you call powershell.exe
from) matters.
注意:
-
此答案主要讨论 Windows PowerShell 可执行文件
powershell.exe
的使用,但它类似地适用于PowerShell Core 可执行文件pwsh
和底部有一个bash
呼叫部分.
This answer primarily discusses use of the Windows PowerShell executable,
powershell.exe
, but it applies analogously to the PowerShell Core executable,pwsh
, and there's a section on calling frombash
at the bottom.
下面的从PowerShell自身调用部分,特别是-File
所需的语法,也适用于将JSON传递给其他程序,例如curl.exe
.
The section Calling from PowerShell itself below, specifically the syntax required with -File
, applies to passing JSON to other programs such as curl.exe
as well.
PowerShell CLI的必需语法-即,使用参数-依赖于 来调用powershell.exe
:
The required syntax for the PowerShell CLI - that is, invoking powershell.exe
with arguments - depends on:
-
是从
cmd.exe
(命令提示符/批处理文件)调用,还是从PowerShell本身(或者在PowerShell Core 中,从类似POSIX的外壳(如bash
)调用).
whether you're calling from
cmd.exe
(Command Prompt / batch file) or from PowerShell itself (or, in PowerShell Core from a POSIX-like shell such asbash
).
是否将参数传递给powershell -Command
(内联命令)或
powerShell -File
(脚本路径).
whether you pass arguments to powershell -Command
(inline command) or powerShell -File
(script path).
无论哪种方式,您最初的尝试都不会成功,因为文字 { "c": "some setting" ... }
由于包含空格而不能被识别为单个参数 .总体而言,strong>和不在引号中;以后添加的带有"..."
的命令缺少对嵌入式"
的转义.
Either way, your original attempt could not have worked, because literal { "c": "some setting" ... }
cannot be recognized as a single argument, due to containing whitespace and not being enclosed in quotes overall; the command added later, with enclosing "..."
, lacks escaping of the embedded "
.
以下命令使用简化的JSON字符串演示了所讨论方案的必需语法.
The following commands demonstrate the required syntax for the scenarios discussed, using a simplified JSON string.
要使-File
命令可运行,请在当前目录中创建一个script.ps1
文件.包含以下内容:ConvertFrom-Json $Args[0]
To make the -File
commands runnable, create a script.ps1
file in the current dir. with the following content: ConvertFrom-Json $Args[0]
-
嵌入的
"
必须以\"
的形式转义(即使内部使用PowerShell- ,也要使用`"
).
Embedded
"
must be escaped as\"
(even though PowerShell-internally you'd use`"
).
重要提示:
-
如果JSON文本包含
cmd.exe
元字符 (总是在\"...\"
次运行之间),则必须^
-分别转义,因为cmd.exe
由于未将\"
识别为转义的"
,因此将这些子字符串视为不带引号的;例如,\"some & setting\"
必须转义为\"some ^& setting\"
;需要在此处转义的cmd.exe
元字符是:
& | < > ^
If the JSON text contains
cmd.exe
metacharacters (invariably between\"...\"
runs), you must^
-escape them individually, becausecmd.exe
, due to not recognizing\"
as an escaped"
, considers these substrings unquoted; e.g.,\"some & setting\"
must be escaped as\"some ^& setting\"
; thecmd.exe
metacharacters that need escaping here are:
& | < > ^
cmd.exe
样式的环境变量引用,例如%USERNAME%
-cmd.exe
没有 literal 字符串语法,它只能识别"..."
,在其中进行 插值,就像未加引号的标记中一样.
如果您想按原样传递这样的令牌,即传递给 suppress 插值,转义语法取决于您是从命令行还是批处理文件,可悲的是:使用前者的%^USERNAME%
和后者的%%USERNAME%%
-请参见此答案获取详细信息.
cmd.exe
-style environment-variable references such as %USERNAME%
are interpolated - cmd.exe
has no literal string syntax, it only recognizes "..."
, where interpolation does take place, just as in unquoted tokens.
If you want to pass such a token as-is, i.e., to suppress interpolation, the escaping syntax depends on whether you're calling from the command line or a batch file, sadly: use %^USERNAME%
from the former, and %%USERNAME%%
from the latter - see this answer for the gory details.
请注意,通过将"..."
字符串括在'...'
中,-Command
调用是如何简单地添加另一层引用.这是必需的,因为对于-Command
,PowerShell将接收到的参数视为PowerShell 源代码,而不是作为文字参数(后者与-File
一起发生).如果不是用于封闭的'...'
,则在解释之前将整个封闭的"..."
剥掉 .
Note how the -Command
calls simply add another layer of quoting, by enclosing the "..."
string in '...'
. This is required, because with -Command
PowerShell treats the arguments it receives as PowerShell source code rather than as literal arguments (the latter is what happens with -File
); if it weren't for the enclosing '...'
, the overall enclosing "..."
would be stripped before interpretation.
使用-File
:
With -File
:
# With a literal string:
powershell -File ./script.ps1 "{ \"c\": \"some setting\", \"unknown\": \"b\" }"
# With an expandable string (expanded by the caller):
powershell -File ./script.ps1 "{ \"c\": \"some %USERNAME%\", \"unknown\": \"b\" }"
使用-Command
:
With -Command
:
# With a literal string:
powershell -Command ConvertFrom-Json '"{ \"c\": \"some setting\", \"unknown\": \"b\" }"'
# With an expandable string (expanded by the caller):
powershell -Command ConvertFrom-Json '"{ \"c\": \"some %USERNAME%\", \"unknown\": \"b\" }"'
从PowerShell本身调用
-
从PowerShell进行调用使转义
cmd.exe
元字符的需求消失了,因为不涉及cmd.exe
.
Calling from PowerShell itself
Calling from PowerShell makes the need to escape
cmd.exe
metacharacters go away, becausecmd.exe
is not involved.使用PowerShell的字符串引用规则,这简化了事情,尽管可悲的是,您仍然需要手动
\
-escape嵌入式"
字符..有关背景信息,请参见此GitHub问题.PowerShell's string-quoting rules apply, which simplifies matters, although, sadly, you still need to manually
\
-escape embedded"
chars.; see this GitHub issue for background.-
使用外部
'...'
引号可简化嵌入式引号的语法,但是将您限制为传递 literal 字符串.
Using outer
'...'
quoting simplifies the syntax for the embedded quoting, but that limits you to passing literal strings.
使用外部
"..."
允许您嵌入来自调用方的变量引用和表达式(由 caller 扩展,在之前传递) ,但是它使语法变得复杂,因为随后必须以\`"
(原文如此)对嵌入式"
进行双重转义:首先使用`
符合PowerShell- internal 语法,然后使用\
满足PowerShell CLI 的要求.Using outer
"..."
allows you to embed variable references and expressions from the caller (which are expanded by the caller, before the argument is passed), but it complicates the syntax, given that an embedded"
must then be doubly escaped as\`"
(sic): first with`
to conform to PowerShell-internal syntax, then with\
to satisfy the PowerShell CLI's requirements.如果您的JSON文本不是文字且存储在变量中,则必须传递
$jsonVar -replace '"', '\"'
来执行必要的转义-请参见If your JSON text is not a literal and stored in a variable, you must pass
$jsonVar -replace '"', '\"'
to perform the necessary escaping - see this answer.使用
-File
或调用外部程序(例如curl.exe
)时:With
-File
or when calling external programs such ascurl.exe
:# With a literal string: powershell -File ./script.ps1 '{ \"c\": \"some setting\", \"unknown\": \"b\" }' # With an expandable string (expanded by the caller): powershell -File ./script.ps1 "{ \`"c\`": \`"some $env:OS\`", \`"unknown\`": \`"b\`" }"
使用
-Command
:With
-Command
:# With a literal string: powershell -Command ConvertFrom-Json '''"{ \"c\": \"some setting\", \"unknown\": \"b\" }"''' # With an expandable string (expanded by the caller): powershell -Command ConvertFrom-Json "'{ \`"c\`": \`"some $env:OS\`", \`"unknown\`": \`"b\`" }'"
PowerShell Core :从
调用bash
-
Bash与PowerShell一样,能够理解扩展(内插)的
"..."
字符串和文字的'...'
字符串.
PowerShell Core: Calling from
bash
Bash, like PowerShell, understands both expanding (interpolating)
"..."
strings and literal'...'
strings.Bash与
cmd.exe
不同,将\"
识别为转义的"
字符.在"..."
中,因此无需转义Bash的任何元字符.Bash, unlike
cmd.exe
, recognizes\"
as escaped"
chars. inside"..."
, so there's no need to escape any of Bash's metacharacters.使用
-File
:With
-File
:# With a literal string: pwsh -File ./script.ps1 '{ "c": "some setting", "unknown": "b" }' # With an expandable string (expanded by the caller): pwsh -File ./script.ps1 "{ \"c\": \"some $USER\", \"unknown\": \"b\" }"
使用
-Command
:With
-Command
:# With a literal string: pwsh -Command ConvertFrom-Json \''{ "c": "some setting", "unknown": "b" }'\' # With an expandable string (expanded by the caller): pwsh -Command ConvertFrom-Json "'{ \"c\": \"some $USER\", \"unknown\": \"b\" }'"
这篇关于如何将JSON(字符串数据)传递到PowerShell?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
-