I have this function
function Get-JsonContent{
param (
[Parameter(
Mandatory = $true,
HelpMessage = "Path to the json config file."
)]
[string] $Filepath
)
$content = Get-Content -Path $Filepath -Raw
$config = $content | ConvertFrom-Json -NoEnumerate
return $config
}
That basically just reads the json, I noticed that single element json arrays get converted into an object, and this can be solved by using the -NoEnumerate parameter at least from powershell seven. By doing this however I only notice this works when I pipe the ConvertFrom-Json with Convert-ToJson
So for example
ConvertFrom-Json $var -NoEnumerate | ConvertTo-Json
However the below implementation doesn't work I for example read two json files, merge the files the convert the output to json, so not entirely sure how that would work.I could use the -Array option but I also have other objects I don't want to convert to arrays
I have this function
function Get-JsonContent{
param (
[Parameter(
Mandatory = $true,
HelpMessage = "Path to the json config file."
)]
[string] $Filepath
)
$content = Get-Content -Path $Filepath -Raw
$config = $content | ConvertFrom-Json -NoEnumerate
return $config
}
That basically just reads the json, I noticed that single element json arrays get converted into an object, and this can be solved by using the -NoEnumerate parameter at least from powershell seven. By doing this however I only notice this works when I pipe the ConvertFrom-Json with Convert-ToJson
So for example
ConvertFrom-Json $var -NoEnumerate | ConvertTo-Json
However the below implementation doesn't work I for example read two json files, merge the files the convert the output to json, so not entirely sure how that would work.I could use the -Array option but I also have other objects I don't want to convert to arrays
Share Improve this question asked Mar 10 at 19:01 John KiraguJohn Kiragu 1411 silver badge11 bronze badges 2 |1 Answer
Reset to default 3Think that every object outputted from a script block, function or cmdlet is enumerated, and due to this, if the object being enumerated happens to be a single element array then PowerShell dynamically assigns it as a scalar value. The -NoEnumerate
parameter prevents this enumeration from happening, however this only works once, when the cmdlet outputs. In your case, you have a variable assignment from the cmdlet, the array is preserved up until this point, but then when you use that variable as output the enumeration isn't prevented. The about_Pipelines documentation is probably the one that goes more in depth with this and also explains why this enumeration behavior is required.
Perhaps this simple example helps you visualize it, Write-Output -NoEnumerate
can help us emulate what is happening in your case:
# the array is enumerated and assigned as a scalar
$config = & { @(1) }
$config.GetType() # Type: int
# `-NoEnumerate` prevents the script block enumeration
$config = & { Write-Output @(1) -NoEnumerate }
$config.GetType() # Type: object[]
# the use of the variable assignment enumerates the value
$config = & { $config = Write-Output @(1) -NoEnumerate; $config }
$config.GetType() # Type: int
So, by simply removing the assignment the issue should be solved:
function Get-JsonContent {
param (
[Parameter(
Mandatory = $true,
HelpMessage = 'Path to the json config file.'
)]
[string] $Filepath
)
Get-Content -Path $Filepath -Raw | ConvertFrom-Json -NoEnumerate
}
$config =
just return from$content | ConvertFrom-Json -NoEnumerate
and it should preserve the array. Compare:& { $a = '[{"foo": "bar"}]' | ConvertFrom-Json -NoEnumerate; $a } | ConvertTo-Json
versus& { '[{"foo": "bar"}]' | ConvertFrom-Json -NoEnumerate } | ConvertTo-Json
– Santiago Squarzon Commented Mar 10 at 19:08,
, meaning:return ,$config
– iRon Commented Mar 11 at 9:07