skip to Main Content

I’m trying to create a JSON array using:

$bodyObject = @(
    @{    
        'Username' = '[email protected]'        
    }
)

$body = $bodyObject | ConvertTo-Json

But the $body object doesn’t contain the square brackets:

{
    "Username":  "[email protected]"
}

If I add another element to the array, the code works perfectly:

$bodyObject = @(
    @{    
        'Username' = '[email protected]'        
    },
    @{    
        'Username' = '[email protected]'        
    }
)

$body = $bodyObject | ConvertTo-Json
<# Output:
[
    {
        "Username":  "[email protected]"
    },
    {
        "Username":  "[email protected]"
    }
]
#>

How can I get one element arrays to generate JSON containing the square brackets?

2

Answers


  1. The simplest way to do it is to pass the array positionally instead of through the pipeline:

    $body = ConvertTo-Json $bodyObject
    

    Reason why you don’t see the array in the first example is because the pipeline enumerates.

    Login or Signup to reply.
  2. To complement Santiago’s helpful answer:

    • The enumeration behavior of PowerShell’s pipeline means that a receiving command fundamentally cannot tell the difference between pipeline input that was provided as (a) a single input object or (b) as a single-element array.

      • That is, the following two commands both send a single [int] instance through the pipeline:

        • (42 | ForEach-Object GetType).Name -> Int32
        • (@(42) | ForEach-Object GetType).Name -> Int32
    • By contrast, when passing input as an argument, the target command can make such a distinction – if designed to do so – and ConvertTo-Json does.

      • However, it is rare for cmdlets to make this distinction – see GitHub issue #4242 for a discussion.

    As an alternative to passing input by argument, PowerShell (Core) 7+ introduced the
    -AsArray switch
    , which requests that even a single input object (which may have been a single-element array originally) be treated as an array in its JSON representation.

    # PS v7+ only; ditto for @(42) as input.
    42 | ConvertTo-Json -AsArray -Compress # -> '[42]'
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search