如何使用 powershell 为 aws 格式化 json 字符串

how to format json string for aws with powershell

我想通过 powershell 脚本中的 cli 命令向 aws 发送事件。这是我需要发送到 eventbridge 的 Json:

   [
       {
          "Sensor":"{\"id\":\"880/2021-04-13\",\"attributes\":\"green\",\"Name\":\"SensorGreen\",\"state\":\"SUCCEEDED\"}",
          "Source":"google.com"
       }

    ]

那是在 powershell 中尝试过的:

$json='[{"Sensor":"{\"id\":\"880/2021-04-13\",\"attributes\":\"green\",\"Name\":\"SensorGreen\",\"state\":\"SUCCEEDED\"}","Source":"google.com"}]'|ConvertTo-Json -Compress

aws events put-events --entries $json --region "eu-central-1"  

那是行不通的。我什至尝试将它写入 json 文件并读取它并从文件发送它,但它不起作用。它以某种方式导致我的“传感器”在必要时出现过多的“\”斜线或没有斜线。我什至尝试创建一个对象并将传感器对象转换为 Json,然后再次将整个对象进行转义,但它不起作用。

编辑:

i tried also this as mentioned in the answer:
$RequestObject = [pscustomobject] @(@{
    Sensor = [pscustomobject] @{
        id = "880/2021-04-13"
        attribute = "green"
        Name = "SensorGreen"
        state = "SUCCEEDED"
    }
    Source = "google.com"
})
$RequestObject.Get(0).Sensor=$RequestObject.Get(0).Sensor | ConvertTo-Json -Compress
$Json = $RequestObject | ConvertTo-Json -Compress
aws events put-events --entries $Json --region "eu-central-1"

我包含了 @() 以拥有一个数组并将传感器对象两次转换为 json 以包含斜线。但结果是:

Error parsing parameter '--entries': Invalid JSON: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

如果我仅将命令行界面与 aws 命令一起使用并将对象直接放入命令中,那么它可以工作..但 powershell 不会。

ConvertTo-Json 用于在 PowerShell 中转换对象,而不是您已尝试在 Json 中写入的字符串。你的 $Json 变量产生这个。

"[{\"Sensor\":\"{\\"id\\":\\"880/2021-04-13\\",\\"attributes\\":\\"green\\",\\"Name\\":\\"SensorGreen\\",\\"state\\":\\"SUCCEEDED\\"}\",\"Source\":\"google.com\"}]"

如果您想在 PowerShell 中创建对象并将其转换为 Json,那么您可以这样做。

$RequestObject = [pscustomobject] @{
    Sensor = [pscustomobject] @{
        id = "880/2021-04-13"
        attribute = "green"
        Name = "SensorGreen"
        state = "SUCCEEDED"
    }
    Source = "google.com"
}
$Json = $RequestObject | ConvertTo-Json -Compress
aws events put-events --entries $Json --region "eu-central-1"

如果您打印变量,您的 Json 将如下所示。

{"Sensor":{"id":"880/2021-04-13","attribute":"green","Name":"SensorGreen","state":"SUCCEEDED"},"Source":"google.com"}

我认为这类似于命令所期望的 Json。不完全确定为什么需要转义字符串或数组。这里是未压缩的。

{
    "Sensor":  {
                   "id":  "880/2021-04-13",
                   "attribute":  "green",
                   "Name":  "SensorGreen",
                   "state":  "SUCCEEDED"
               },
    "Source":  "google.com"
}

刚刚注意到 powershell-2.0 标签。如果您正在使用它,那么您应该这样做来创建您的 Json.

$Sensor = New-Object psobject -Property @{
    id = "880/2021-04-13"
    attribute = "green"
    Name = "SensorGreen"
    state = "SUCCEEDED"
}
$RequestObject = New-Object psobject -Property @{
    Sensor = $Sensor
    Source = "google.com"
}
$Json = $RequestObject | ConvertTo-Json -Compress

编辑

如果您绝对必须以这种方式转义字符串并拥有单个项目数组,那么您应该直接传递您在答案中写入的 Json,无需任何进一步转换。

$json='[{"Sensor":"{\"id\":\"880/2021-04-13\",\"attributes\":\"green\",\"Name\":\"SensorGreen\",\"state\":\"SUCCEEDED\"}","Source":"google.com"}]'

如果您想让 PowerShell 为您执行此操作,则需要先对 Sensor 对象执行一些字符串替换。

PowerShell 2.0

$Sensor = New-Object psobject -Property @{
    id = "880/2021-04-13"
    attribute = "green"
    Name = "SensorGreen"
    state = "SUCCEEDED"
} 
$SensorJson = $Sensor | ConvertTo-Json -Compress
$SensorJson.Replace("`"","\`"")
$RequestObject = New-Object psobject -Property @{
    Sensor = $SensorJson
    Source = "google.com"
}
$Json = $RequestObject | ConvertTo-Json -Compress

PowerShell 3.0+

$Sensor = [pscustomobject] @{
    id = "880/2021-04-13"
    attribute = "green"
    Name = "SensorGreen"
    state = "SUCCEEDED"
}
$SensorJson = $Sensor | ConvertTo-Json -Compress
$SensorJson.Replace("`"","\`"")
$RequestObject = [pscustomobject] @{
    Sensor = $SensorJson
    Source = "google.com"
}
$Json = $RequestObject | ConvertTo-Json -Compress

然后你的 AWS 命令​​

# Add the array around the compressed Json string.
aws events put-events --entries "[$Json]" --region "eu-central-1"

"[$Json]" 打印

[{"Sensor":"{\"id\":\"880/2021-04-13\",\"attribute\":\"green\",\"Name\":\"SensorGreen\",\"state\":\"SUCCEEDED\"}","Source":"google.com"}]
  • 您正在 将 JSON 字符串传递给 外部程序 (aws)

  • 无论您如何构建该字符串 - 直接作为字符串,或通过 ConvertTo-Json 从对象/哈希表中构建 - 从 PowerShell 7.1 开始 - manual 需要将嵌入式 " 转义为 \",这反过来又需要将嵌入式 " 之前的现有 \ 转义为 \.

    • 注意:None 这应该是必要的,但由于 PowerShell 中的一个长期存在的错误是 - 请参阅 this answer 了解详情。

    • PowerShell Core 7.2.0-preview.5 现在包括 experimental feature PSNativeCommandArgumentPassing with an attempted fix, but, unfortunately, it looks like it will lack important accommodations for high-profile CLIs on Windows - see this summary from GitHub issue #15143。但是,它 修复对 aws.exe Amazon Web Services CLI 的调用。

# The JSON string to be passed as-is.
$json = @'
[
  {
     "Sensor":"{\"id\":\"880/2021-04-13\",\"attributes\":\"green\",\"Name\":\"SensorGreen\",\"state\":\"SUCCEEDED\"}",
     "Source":"google.com"
  }

]
'@

# Up to at least PowerShell 7.1:
# Manually perform the required escaping, to work around PowerShell's
# broken argument-passing to external programs.
# Note:
#  -replace '\', '\' *looks* like a no-op, but replaces each '\' with '\'
$jsonEscaped = $json -replace '\', '\' -replace '"', '\"'

# Now pass the *escaped* JSON string to the aws CLI:
aws events put-events --entries $jsonEscaped --region "eu-central-1"