ConvertTo-Json with an array with multiple items

Viewed 181

I am trying to write a PS script with an array for multiple items using ConvertTo-Json. I need this script to use in Azure DevOps pipeline. For example, using variables I could convert multiple items into Json. The script works for a single item as I want, but cannot figure out how to feed multiple items as one variable.

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

What I need to achieve is to add more items into every single variable, so an output would be as below with two users

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

I tried to use variables using an array as @("Reader"; "Reader"), but the output is not what I need. Can someone please help to achieve it? Thanks!

2 Answers

Note: Steven's answer and its code formatting put my answer to shame so you should definitely use the formatting he shows if you have a defined static list that you need to convert to JSON.

That being said, I am leaving my answer for reference, as it might still be useful to know that you can do it through the creation of a PSObject list in the event the number of items you needed to add was dynamically picked up from somewhere.

If that is your scenario, then

  • Creating a PSObject list
  • Appending dynamically all items to it picked up from another source
  • Converting the list to a json object

would be the way to go. For list where you can hardcode the layout of your final json (eg: defined number of items), then his answer x 1000.


Original answer

You can create a list of PSObject, then add your items into it and convert it to json, like so.

$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

Note that you don't thave to do the whole PSCustomObject / Value fill / Add in one line. I like to do it like that when I have very small psobject but you can aerate your code a bit more. A more vertically inclined version of the same thing.

$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

Side note If you need to go deeper than 4 level with your Json, don't forget to add -Depth X parameter with the desired depth. This is because ConvertTo-Json default behavior is to convert an object only up to the fourth depth layer.

If you want objects to be represented in the resulting JSON you should feed objects into the ConvertTo-Json cmdlet. Similar to 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

You can also shorten with:

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

$UserList

Unless we are misunderstanding the issue, I don't see a reason to store the array elements in discrete variables first. It's an array of objects you want and that will need to be created somewhere. If there is input that goes with your project it might help.

Related