【问题标题】:Powershell Nested Json doesn't look like a JsonPowershell 嵌套 Json 看起来不像 Json
【发布时间】:2021-10-25 01:06:53
【问题描述】:

我目前正在尝试为 API 调用准备一个 JSON 主体,它应该看起来像这样

curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/api/alert -d '{
  "title": "Other alert",
  "description": "alert description",
  "type": "external",
  "source": "instance1",
  "sourceRef": "alert-ref",
  "severity": 3,
  "tlp": 3,
  "artifacts": [
    { "dataType": "ip", "data": "127.0.0.1", "message": "localhost" },
    { "dataType": "domain", "data": "thehive-project.org", "tags": ["home", "TheHive"] },
  ],
  "caseTemplate": "external-alert"
}'

但是问题是我用 powershell 创建的 json 正文有奇怪的字符,看不出问题出在哪里。这是我的 JSON 正文

{
    "tlp":  1,
    "source":  "Test",
    "title":  "Test Alert1",
    "artifacts":  "{\r\n    \"dataType\":  \"ip\",\r\n    \"data\":  \"127.0.0.1\"\r\n}",
    "type":  "external",
    "sourceRef":  "1",
    "description":  "Test",
    "severity":  1
}

我按如下方式创建这个 JSON 主体。我已经尝试过 CustomObjects 和 Hashtables,但总是得到相同的输出

$body = @{
            title = "$title"
            description = "$Alert_Description"
            type ="external"
            source ="$Source"
            sourceRef ="$SourceRef"
            severity = $Severity
            tlp = $tlp
            $artifacts = [PSCustomObject]@{
            dataType=ip
            data=127.0.0.1}  
        }| ConvertTo-Json
        $JsonBody = $body | ConvertTo-Json

有人可以给我一个提示吗?我已经不知道了

【问题讨论】:

  • 为什么要转换成 json 两次? $body 已经是 JSON 字符串了。
  • @AdminOfThings 我认为嵌套的 Json 可能会有所帮助.. 但事实并非如此

标签: json powershell


【解决方案1】:

首先,修复您的哈希表,以便它创建预期的 JSON 表示,并且只应用 ConvertTo-Json一次

$body = [ordered] @{
  title       = $title
  description = $Alert_Description
  type        = 'external'
  source      = $Source
  sourceRef   = $SourceRef
  severity    = $Severity
  tlp         = $tlp
  artifacts   = , [pscustomobject] @{
    dataType = 'ip'
    data     = '127.0.0.1'
  }  
} | ConvertTo-Json
  • 变量不需要包含在"..." 中,除非您明确想要将它们的值转换为字符串。

  • 诸如ip 之类的文字文本信息确实 需要引用('...',即逐字字符串文字是最好的)。

  • artifacts 属性是示例 JSON 中的 数组,因此 , 的一元形式,array constructor operator 用于将 [pscustomobject] 实例包装在单个元素中数组。

    • 如果您有多个对象,请将,放在它们之间;如果该数组是先前构造的并存储在一个名为 $arr 的变量中,请使用 artifacts = $arr
  • 使用[ordered],即创建一个有序哈希表并不是绝对必要的,但可以更容易地将生成的JSON表示与输入哈希表进行比较。

  • 通常请记住,在特定情况下需要在 ConvertTo-Json 中显式使用 -Depth 参数,以确保属性不会被截断 - 请参阅 this post 了解更多信息。但是,对于您问题中的哈希表,这恰好不是成为问题。


其次,由于您要将 json 发送到 外部程序curl(请注意,在 Windows PowerShell 中,您必须使用 curl.exe为了绕过 Invoke-WebRequest 的内置 curl 别名,额外的转义步骤 - 不幸的是 - 至少需要 v7.1 - 尽管在 v7.2 中可能会发生变化: 由于 PowerShell 中的一个长期存在的错误,嵌入在 $body 值中的" 实例必须手动转义为 \"

curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' `
  http://127.0.0.1:9000/api/alert -d ($body -replace '([\\]*)"', '$1$1\"')

注意:对于您的特定示例 JSON,-replace '"', '\"' 可以。

请参阅this answer 了解更多信息。

【讨论】:

  • 主要问题是变量周围的“”,我不知道这会产生一些奇怪的字符。但我对工件部分有点困惑。我试图向这样的工件属性添加两个 abject,但它没有工作 $collection = New-Object System.Collections.ArrayList $collection.Add([pscustomobject] @{dataType = 'username' data = $ Username}) $collection.Add([pscustomobject] @{dataType = 'username' data = $Username}) artifacts = $collection.ForEach($_)
  • @StefanRöthlisberger:在"..." 中包含变量引用本质上调用变量上的.ToString(),使用不变的文化,并对数组进行特殊处理,将其字符串化为空格分隔的列表他们的(字符串化)元素(尝试"$(1,2,3)"。至于artifacts 部分:artifacts = $collection
【解决方案2】:

在您的 ConvertTo-Json 上打一个“-Depth 50”,这应该可以解决您的问题。

喜欢这里:ConvertTo-Json flattens arrays over 3 levels deep

【讨论】:

  • 虽然这通常是一个很好的提示,但 -Depth 不需要获得问题中哈希表的完整 JSON 表示(它嵌套的深度不足以成为问题),而代码还有其他明显的问题。
猜你喜欢
  • 1970-01-01
  • 2016-09-02
  • 2020-03-13
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2023-03-29
  • 2020-06-03
相关资源
最近更新 更多