3

Why does the following not iterate over the elements of the System.object[] array returned by ConvertFrom-Json:

 ConvertFrom-Json '[1, 2, 3]'   | ForEach-Object  {": $_"}

but this does:

(ConvertFrom-Json '[1, 2, 3]')  | ForEach-Object  {": $_"}

It seems to me that in the first case the whole array gets passed as a parameter to ForEach but the reason isn't clear to me.

Update: this appears to be a bug in Powershell related to the conversion of arrays, see here and here.

Community
  • 1
  • 1
deorst
  • 761
  • 3
  • 13
  • Indeed, this is interesting https://puu.sh/ump6h/bb33b203fc.png – wOxxOm Feb 27 '17 at 17:33
  • Ok, so `$conv = ConvertFrom-Json '[1, 2, 3]'; $conv | ForEach {$_.gettype()}` works as expected. Why does the array get unpacked during variable assignment but not when piping it? This doesn't make a whole lot of sense to me. – deorst Feb 27 '17 at 18:49
  • Compare to `&{,@(1,2,3)}|% "$_"` v `&{@(1,2,3)}|% "$_"` – Mathias R. Jessen Feb 27 '17 at 20:54
  • 2
    @deorst Bugs, which you are pointed is actually "bugs" in `ConvertTo-Json`, not in `ConvertFrom-Json`. Also, behavior you seeing have nothing to do with `ConvertFrom-Json` in particular. It is totally expected, by me at least, PowerShell behavior. `function f {,(1..5)}; f | % GetType; (f) | % GetType` – user4003407 Feb 27 '17 at 21:28

1 Answers1

2

Copying from my answer here:

ConvertFrom-Json has some odd behavior with pipelines. The issue is that ConvertFrom-Json wraps the JSON array in an array and then passes the whole array down the pipeline as one item. This is fine in most cases, but if the outermost level is a JSON array, then that whole array gets passed as a single object into the pipeline.

Compare:

PS> ConvertFrom-Json '[1, 2, 3]' | ForEach-Object  {": $_"}
: 1 2 3

PS> (ConvertFrom-Json '[1, 2, 3]') | ForEach-Object  {": $_"}
: 1
: 2
: 3

PS> $x = ConvertFrom-Json '[1, 2, 3]'
PS> $x | ForEach-Object  {": $_"}
: 1
: 2
: 3
PS> ,$x | ForEach-Object  {": $_"}
: 1 2 3

Note with that last example we can duplicate the problem with the unary comma operator.

The issue has been reported here for PowerShell Core 6.

Bacon Bits
  • 30,782
  • 5
  • 59
  • 66