admin管理员组

文章数量:1410712

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
  • remove the assignment $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
  • Try using the Comma operator ,, meaning: return ,$config – iRon Commented Mar 11 at 9:07
Add a comment  | 

1 Answer 1

Reset to default 3

Think 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
}

本文标签: jsonSingle element array serialization in powershellStack Overflow