【问题标题】:ConvertTo-Json with an array with multiple items带有多个项目的数组的 ConvertTo-Json
【发布时间】:2021-08-13 22:08:23
【问题描述】:

我正在尝试使用ConvertTo-Json 为多个项目编写一个包含数组的 PS 脚本。我需要在 Azure DevOps 管道中使用此脚本。例如,使用变量我可以将多个项目转换为 Json。该脚本适用于我想要的单个项目,但无法弄清楚如何将多个项目作为一个变量提供。

# Variables
$Roles = "Reader"
$Name = "User1"
$Email = "user1@email.com"

$UserList = ConvertTo-Json @(@{Roles = @("$Roles"); Name = "$Name"; Email = "$Email"})

# Output for a single item as I need
PS C:\> $UserList
[
    {
        "Email":  "user1@email.com",
        "Name":  "User1",
        "Roles":  [
                      "Reader"
                  ]
    }
]

我需要实现的是在每个变量中添加更多项目,因此输出将如下所示,有两个用户

[
        {
            "Email":  "user1@email.com",
            "Name":  "User1",
            "Roles":  [
                          "Reader"
                      ]
        },
        {
            "Email":  "user2@email.com",
            "Name":  "User2",
            "Roles":  [
                          "Reader"
                      ]
        }
] 

我尝试使用数组作为@("Reader"; "Reader") 使用变量,但输出不是我需要的。有人可以帮助实现它吗?谢谢!

【问题讨论】:

  • 不确定我是否关注,您可以通过管道将一组用户及其邮件和角色传递到ConvertTo-Json 以获得所需的输出。

标签: powershell


【解决方案1】:

如果您希望在生成的 JSON 中表示对象,您应该将对象提供给 ConvertTo-Json cmdlet。类似于Sage's fine answer:

$Objects =
@(
    [PSCustomObject]@{
        Name  = "User1"
        Email = "user1@email.com"
        Roles = @("Reader")
    }
    [PSCustomObject]@{
        Name  = "User2"
        Email = "user2@email.com"
        Roles = @("Reader")
    }
)

$UserList = $Objects | ConvertTo-Json

$UserList

您也可以使用以下方式缩短:

$UserList =
@(
    [PSCustomObject]@{
        Name  = "User1"
        Email = "user1@email.com"
        Roles = @("Reader")
    }
    [PSCustomObject]@{
        Name  = "User2"
        Email = "user2@email.com"
        Roles = @("Reader")
    }
) | ConvertTo-Json

$UserList

除非我们误解了这个问题,否则我认为没有理由首先将数组元素存储在离散变量中。这是您想要的对象数组,需要在某处创建。如果有与您的项目相关的输入,它可能会有所帮助。

【讨论】:

  • 这很漂亮。不确定我的头在哪里,但这是我更喜欢静态列表的方式。我留下了我的答案,因为如果数据是动态获取的,这可能会很有用,否则,这 x 1000
  • 感谢@Steven 的解决方案。它绝对帮助我更好地了解数组和 PSCustomObject。我仍然不明白这一点,是否可以根据变量的动态项创建数组?例如,随着使用您的解决方案创建更多数组而添加更多变量项?提前感谢您的关注!
  • 是的,但我不确定我是否理解这个问题。所显示的基本原理在许多情况下都有效,可能需要根据这些变量是什么、它们的表述方式等进行调整。
【解决方案2】:

注意:Steven's answer and its code formatting 让我的回答感到羞耻,所以如果你有一个定义的静态列表需要转换为 JSON,你绝对应该使用他显示的格式。

话虽如此,我将我的答案留作参考,因为如果您需要添加的项目数被动态提取,知道您可以通过创建 PSObject 列表来完成它可能仍然有用从某个地方。

如果这是你的场景,那么

  • 创建 PSObject 列表
  • 动态附加从其他来源获取的所有项目
  • 将列表转换为 json 对象

将是要走的路。 对于可以硬编码最终 json 布局的列表(例如:定义的项目数),然后是他的答案 x 1000。


原答案

您可以创建一个 PSObject 列表,然后将您的项目添加到其中并将其转换为 json,就像这样。

$UserListObj = [System.Collections.Generic.List[PSObject]]::new()
$UserListObj.Add(([PSCustomObject]@{Email = "user1@email.com"; Name = "User1"; Roles = @("Reader") }))
$UserListObj.Add([PSCustomObject]@{Email = "User2@email.com"; Name = 'User 2'; Roles = @('Reader', 'Collaborator') })
$UserList = ConvertTo-Json $UserListObj

请注意,您不必在一行中完成整个 PSCustomObject / 值填充 / 添加。当我的 psobject 非常小的时候,我喜欢这样做,但你可以让你的代码更加活跃。同一事物的更垂直倾斜的版本。

$UserListObj = [System.Collections.Generic.List[PSObject]]::new()

$User1 = [PSCustomObject]@{
        Email = "user1@email.com" 
        Name  = "User1"
        Roles = @("Reader") 
    }
$UserListObj.Add($User2)

$User2 = [PSCustomObject]@{
        Email = "user2@email.com" 
        Name  = "User 2"
        Roles = @("Reader","Collaborator") 
    }
$UserListObj.Add($User2)

$UserList = ConvertTo-Json $UserListObj

旁注 如果您的 Json 需要超过 4 级,请不要忘记添加具有所需深度的 -Depth X 参数。这是因为ConvertTo-Json 默认行为是将对象仅转换到第四个深度层。

【讨论】:

  • -Depth参数的远见卓识。
  • 也感谢 Sage 的解决方案,绝对值得关注。我要玩 PSObject 列表,看看我能得到什么:)
猜你喜欢
  • 2013-09-10
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多