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
The simplest way to do it is to pass the array positionally instead of through the pipeline:
Reason why you don’t see the array in the first example is because the pipeline enumerates.
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.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.