如何将JSON(字符串数据)传递到PowerShell? [英] How to pass JSON (string data) to PowerShell?

查看:96
本文介绍了如何将JSON(字符串数据)传递到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 from bash 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 as bash).

是否将参数传递给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, because cmd.exe, due to not recognizing \" as an escaped ", considers these substrings unquoted; e.g., \"some & setting\" must be escaped as \"some ^& setting\"; the cmd.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本身调用

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆