Summary
When ConvertFrom-Yaml parses a top-level YAML sequence (array), the result is written to the pipeline as a single Generic.List1[Object] rather than unrolling into individual elements. This breaks direct piping to downstream cmdlets like Select-Object or Where-Object.
Expected Behaviour
# enumerable (top-level) input sequences should unroll like ConvertFrom-Json
> '[1,2,3]' | ConvertFrom-Json | Select-Object -Last 1
3
# enumerable (top-level) input sequences should unroll like ConvertFrom-Json
> '[1,2,3]' | ConvertFrom-Yaml | Select-Object -Last 1
3
Actual Behaviour
# enumerable input sequences don't unroll, they are passed down the pipeline as one list object
> '[1,2,3]' | ConvertFrom-Yaml | Select-Object -Last 1
1
2
3
Workarounds
NOTE: this appears to be the "intended" use of the module as all examples in the README store output into an intermediate variable
# storing output into a variable lets PowerShell unroll the list
> $x = '[1,2,3]' | ConvertFrom-Yaml
> $x | Select-Object -Last 1
3
# collecting output with parentheses also works
> ('[1,2,3]' | ConvertFrom-Yaml) | Select-Object -Last 1
3
# inject an empty trailing YAML document (I think this difference in behavior is unintended)
> "[1,2,3]`n---" | ConvertFrom-Yaml -AllDocuments | Select-Object -Last 1
3
Suspected cause
I think the issue lies on powershell-yaml:493
# powershell-yaml.psm1
function Convert-YamlSequenceToArray {
# ...
$ret = [System.Collections.Generic.List[object]](New-Object 'System.Collections.Generic.List[object]')
# ...
return , $ret #<-- explicitly prevents unrolling (I think to preserve nested lists??)
# ...
}
# ...
function Convert-YamlDocumentToPSObject {
# ...
'YamlDotNet.RepresentationModel.YamlSequenceNode' {
return Convert-YamlSequenceToArray $Node -Ordered:$Ordered
}
# ...
}
# ...
function ConvertFrom-Yaml {
# ...
if (($documents.Count -eq 1) -or !$AllDocuments) {
return Convert-YamlDocumentToPSObject $documents[0].RootNode -Ordered:$Ordered #<-- directly returns List[Object] without any unrolling, even for the top-level sequence
}
# with more than one document and the `-AllDocuments` switch, it assigns to an intermediate variable, so it does unroll the lists
$ret = @()
foreach ($i in $documents) {
$ret += Convert-YamlDocumentToPSObject $i.RootNode -Ordered:$Ordered
}
return $ret
# ...
}
Possible fix?
Enumerate the list/array results at the ConvertFrom-Yaml cmdlet boundary by either explicitly iterating, by adding parentheses around the Convert-YamlDocumentToPSObject call, or by storing the list into an intermediate variable (which allows powershell to implicitly unroll it).
function ConvertFrom-Yaml {
# ...
if (($documents.Count -eq 1) -or !$AllDocuments) {
$result = Convert-YamlDocumentToPSObject $documents[0].RootNode -Ordered:$Ordered #<-- implicitly unrolls top-level sequence
return $result
}
# ...
}
I applied the above change on my machine and it seems to have fixed the pipeline output for the few YAML arrays I was working with, but I obviously haven't tested all the other varieties of YAML documents, where I'm sure there are edge-cases I'm overlooking.
# with the above change to ConvertFrom-Yaml applied, arrays can be iterated in the pipeline:
> '[1,2,3]' | ConvertFrom-Yaml | Select-Object -Last 1
3
# and nested arrays also appear to work
> '[[9,8,7],[6,5,4],[3,2,1]]' | ConvertFrom-Yaml | Select-Object -Last 1
3
2
1
Summary
When
ConvertFrom-Yamlparses a top-level YAML sequence (array), the result is written to the pipeline as a singleGeneric.List1[Object]rather than unrolling into individual elements. This breaks direct piping to downstream cmdlets likeSelect-ObjectorWhere-Object.Expected Behaviour
Actual Behaviour
Workarounds
NOTE: this appears to be the "intended" use of the module as all examples in the README store output into an intermediate variable
Suspected cause
I think the issue lies on powershell-yaml:493
Possible fix?
Enumerate the list/array results at the
ConvertFrom-Yamlcmdlet boundary by either explicitly iterating, by adding parentheses around theConvert-YamlDocumentToPSObjectcall, or by storing the list into an intermediate variable (which allows powershell to implicitly unroll it).I applied the above change on my machine and it seems to have fixed the pipeline output for the few YAML arrays I was working with, but I obviously haven't tested all the other varieties of YAML documents, where I'm sure there are edge-cases I'm overlooking.