【问题标题】:how to format json string for aws with powershell如何使用powershell为aws格式化json字符串
【发布时间】:2021-08-05 13:58:47
【问题描述】:

我想通过 powershell 脚本中的 cli 命令向 aws 发送事件。这是我需要发送到事件桥的 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 文件并读取它并从文件中发送它,但它不起作用。它以某种方式导致我的“传感器”有太多“\”斜线或没有斜线,这是必要的。我什至尝试创建一个对象并将 Sensor 对象转换为 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 不能。

【问题讨论】:

    标签: json amazon-web-services powershell powershell-2.0 aws-cli


    【解决方案1】:
    • 您正在将 JSON 字符串传递给 外部程序 (aws)

    • 无论您如何构造该字符串 - 直接作为字符串,或通过 ConvertTo-Json 从对象/哈希表 - 从 PowerShell 7.1 开始 - 手动 将嵌入式 " 转义为\" 是必需的,这反过来又需要将嵌入的" 之前的预先存在的\ 转义为\\

      • 注意:这些都不是必需的,但由于 PowerShell 中长期存在的错误,请参阅 this answer 了解详细信息。

      • PowerShell Core 7.2.0-preview.5 现在包含 experimental feature PSNativeCommandArgumentPassing 并尝试修复,但不幸的是,它看起来像将缺少 Windows 上高调 CLI 的重要调整 - 请参阅来自GitHub issue #15143 的摘要。但是,它修复对 Amazon Web Services CLI aws.exe 的调用。

    # 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"  
    

    【讨论】:

      【解决方案2】:

      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"}]
      

      【讨论】:

      • 不错。但我需要 Sensor 对象包含转义,因为我正在调用的端点期望 Sensor 对象是这样的:“Sensor”:“{\”id\”:\“880/2021-04-13\”,\”属性\":\"green\",\"Name\":\"SensorGreen\",\"state\":\"SUCCEEDED\"}"
      • 如果我添加 $RequestObject.Sensor=$RequestObject.Sensor|ConvertTo-Json -Compress 作为倒数第二个语句。我可以将反斜杠放在 Sensor 对象上。然后我得到了我想要的,但是使用 cli,它给了我错误:解析参数时出错'--entries':无效 JSON:期望用双引号括起来的属性名称:第 1 行第 2 列(字符 1)
      • 并且该数组仍然丢失。最后它是一个包含一个对象的数组。
      • 这对我来说似乎是一个奇怪的模式,并且在检查时,它似乎并不是here in the docs for your command 所反映的。也许我弄错了,我不使用 AWS。
      • 它是一个自定义的东西,所以调用 iam 会在必须这样的地方再次处理。我更新了我的答案,所以你可以看到我得到的结果
      猜你喜欢
      • 2020-04-02
      • 2017-01-01
      • 1970-01-01
      • 2022-03-30
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多