Skip to content

Streams

Work on YAML as YAML, without projecting it to PowerShell values.

Command Purpose
Test-Yaml Test YAML syntax, tags, duplicate keys, and configured resource limits.
Format-Yaml Normalize YAML streams without projecting representation nodes to PowerShell values.
Merge-Yaml Merge complete YAML streams without losing representation graph details.

These three commands share one defining property: they operate on YAML text at the representation level and never project to PowerShell objects. That is what separates them from Conversion. A stream keeps its node kinds, effective tags, anchors and aliases, complex keys, recursive graphs, empty documents and mapping order all the way through, because nothing is ever turned into a PSCustomObject or a dictionary along the way.

Practical consequence: values that cannot survive a PowerShell projection — a sequence used as a mapping key, a !!set, a node that references itself, a mapping whose keys collide only by case — pass through these commands intact.

Validate YAML

powershell if (Get-Content -Path '.\config.yaml' | Test-Yaml) { 'The YAML stream is valid.' }

Test-Yaml uses the same parser and limits as ConvertFrom-Yaml. It returns $false for YAML-specific failures, including duplicate keys and resource limit violations. Unexpected runtime failures are not suppressed, so a genuine bug still surfaces as an error instead of a quiet $false.

Use it as a gate before a more expensive step:

powershell Get-ChildItem -Path '.\manifests' -Filter '*.yaml' | Where-Object { -not (Get-Content -LiteralPath $_.FullName | Test-Yaml) } | Select-Object -ExpandProperty FullName

Format YAML streams

Format-Yaml normalizes existing YAML without converting it through PSCustomObject or dictionary values. It retains document order and empty documents, node kinds, scalar content, effective tags, anchors and aliases, recursive graphs, complex keys, collection structure, and mapping order.

powershell $normalized = Get-Content -Path '.\config.yaml' | Format-Yaml -Indent 4

Pipeline records are joined with LF and parsed as one stream. The output is one string with LF line endings and no final newline. Every document starts with ---; document-end markers, comments, directives, flow presentation, scalar styles, and original anchor names are normalized. Effective standard tags use !! shorthand where possible, while local and global tags use a deterministic verbatim form.

Formatting is byte-idempotent at the same options:

powershell $normalized -ceq ($normalized | Format-Yaml -Indent 4)

-Indent accepts 2 through 9 spaces. The -Depth, -MaxNodes, -MaxAliases, -MaxScalarLength, -MaxTagLength, -MaxTotalTagLength, and -MaxNumericLength defaults and ranges match ConvertFrom-Yaml. Invalid YAML, duplicate representation keys, undefined aliases, malformed tags, and resource limit violations terminate with the same classified YAML errors as parsing.

Merge YAML streams

Merge-Yaml combines two or more complete YAML streams directly through their representation graphs. Every array element or pipeline record is one complete stream, and every stream must contain the same positive document count. Later streams have higher precedence, and documents merge pairwise by zero-based index.

powershell $baseYaml = Get-Content -LiteralPath '.\base.yaml' -Raw $overlayYaml = Get-Content -LiteralPath '.\overlay.yaml' -Raw $mergedYaml = Merge-Yaml -InputObject @($baseYaml, $overlayYaml)

Compatible mappings merge recursively by structural YAML key equality. Base key order remains stable, replacing a value retains its position, and new overlay keys append in overlay order. Complex and tagged keys are supported. Structural fingerprints select comparison candidates only; mutation-aware indexes are retained across overlays, and graph-aware equality makes the final key decision.

Compatible sequences use -SequenceAction Replace, Append, or Unique. Unequal scalars, collection kinds, and incompatible effective tags use -ConflictAction Replace or Error. A later YAML null uses -NullAction Replace or Ignore; ignoring retains an existing prior node, including at a document root.

powershell $baseYaml, $environmentYaml, $secretYaml | Merge-Yaml -SequenceAction Unique -ConflictAction Error -Indent 4

Tags, anchors, aliases, repeated nodes, cycles, mapping order, and selected representation nodes remain graph data. Inputs are immutable, and YAML 1.1 << merge keys remain ordinary mapping entries rather than being expanded. Output is one deterministic string with LF line endings, explicit document starts, and no final newline.

The parser safety parameters and defaults match Format-Yaml. -MaxNodes limits each parsed stream and applies independently to invocation-wide clone creation, charged merge operations, and the resulting stream graph. Index, fingerprint, candidate, alias-traversal, and equality work all consume the merge operation budget. Alias and expanded-tag budgets are also enforced on the result.

Choosing between Streams and Conversion

You want to Use
Read configuration values into PowerShell ConvertFrom-Yaml or Import-Yaml
Check a file before using it Test-Yaml
Canonicalize YAML for diffing or storage Format-Yaml
Layer environment or secret overlays onto a base file Merge-Yaml
Emit YAML from PowerShell values ConvertTo-Yaml or Export-Yaml

If the YAML must come back out looking like YAML, stay in this group. If you need to read or compute with the data, cross over to Conversion.