Yaml converts between YAML streams and PowerShell values. Its parser,
schema construction, graph projection, and emitter are implemented in the
module's PowerShell source, with no external parser library or runtime
assembly dependency.
Compatibility target: PowerShell Core LTS and newer, with the source and
artifact contract pinned to PowerShell 7.6 (CompatiblePSEditions = 'Core').
The implementation is layered: Unicode and c-printable validation feeds a document/directive scanner; context-aware block and flow readers produce syntax tokens; an iterative composer builds the representation graph; the core-schema constructor and PowerShell projector create public values. Serialization uses a separate safe value classifier, iterative reference-graph normalizer, and presentation emitter. Internal arrays, nulls, and byte arrays move through boxed values rather than the PowerShell pipeline.
Install-PSResource -Name Yaml
Import-Module -Name YamlThe module exports:
| Command | Purpose |
|---|---|
ConvertFrom-Yaml |
Parse one or more YAML documents into PowerShell values. |
ConvertTo-Yaml |
Serialize supported PowerShell values as YAML 1.2-compatible text. |
Test-Yaml |
Test YAML syntax, tags, duplicate keys, and configured resource limits. |
Ordinary string-key mappings become ordered PSCustomObject values. A
top-level sequence writes its items to the pipeline by default.
$config = @'
name: example
enabled: true
ports: [80, 443]
'@ | ConvertFrom-Yaml
$config.name
$config.ports[0]Pipeline strings are joined with LF and parsed as one stream. This makes line-oriented input work as expected:
$config = Get-Content -Path '.\config.yaml' | ConvertFrom-YamlUse -NoEnumerate when a top-level sequence must remain one pipeline record:
$servers = @'
- name: web-1
- name: web-2
'@ | ConvertFrom-Yaml -NoEnumerateEvery YAML document is returned separately:
$documents = @(@'
---
name: first
---
name: second
'@ | ConvertFrom-Yaml)Use -AsHashtable for insertion-ordered dictionaries and mappings with
complex, non-string, empty, or case-colliding keys:
$mapping = @'
? [region, port]
: eu-1
'@ | ConvertFrom-Yaml -AsHashtableConvertTo-Yaml supports PSCustomObject and explicit PSObject note-property
bags, dictionaries, sequences, strings, characters, Booleans, integer and
floating-point numbers, BigInteger, DateTime, DateTimeOffset, enums,
null, and byte arrays.
$yaml = [ordered]@{
name = 'example'
enabled = $true
ports = @(80, 443)
} | ConvertTo-Yaml -ExplicitDocumentStart
$roundTrip = $yaml | ConvertFrom-YamlMultiple pipeline records are collected into one top-level YAML sequence:
'one', 'two' | ConvertTo-YamlPass an array directly when it represents one input value:
$items = @('one', 'two')
ConvertTo-Yaml -InputObject $items-EnumsAsStrings emits enum names instead of their underlying numeric values.
-Indent accepts 2 through 9 spaces. -Depth, -MaxNodes, and
-MaxScalarLength constrain serialization. The maximum supported depth is
128, and the default is 100.
Repeated acyclic collection references are emitted with anchors and aliases.
Cyclic graphs and unsupported runtime objects fail specifically; values are
never silently truncated or converted with ToString().
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.
- Plain implicit scalars use the YAML 1.2 core schema. YAML 1.1-only Boolean
words such as
yesand untagged timestamps remain strings. - Standard explicit tags are handled without reflection:
str,null,bool,int,float,binary,timestamp,seq,map,set,omap, andpairs. - Unknown application tags are discarded safely. Tagged scalars become strings and tagged collections retain their sequence or mapping shape.
- Duplicate mapping keys are rejected after scalar construction, including structurally equal complex keys.
- Aliases preserve collection reference identity where PowerShell can represent it.
- YAML merge keys are not expanded;
<<is ordinary mapping data under the YAML 1.2 core schema. - Parsing defaults to depth 100, 100000 nodes, 1000 aliases, 1048576 decoded characters per scalar, 1024 characters per expanded tag, 65536 cumulative expanded tag characters, and 4096 digits per numeric scalar. The corresponding limit parameters can be lowered for untrusted input.
- The public maximum depth of 128 is exercised for parsing and serialization in fresh PowerShell 7.6+ artifact tests.
Default object projection requires mapping keys that can be represented
without loss as PowerShell properties. Use -AsHashtable when that restriction
does not fit the data.
The offline test gate runs the latest official yaml-test-suite source release,
v2022-01-17, at commit 45db50aecf9b1520f8258938c88f396e96f30831.
Its data-2022-01-17 export is pinned at commit
6e6c296ae9c9d2d5c4134b4b64d01b29ac19ff6f with archive SHA-256
47C173AFFEB480517B30FB77DC8C76FD48609B9B65DD1C1D3D0D0BAEE48D6AA9.
The archive contains 402 inputs:
| Surface | Pass | PolicyDifference | Fail | NotApplicable |
|---|---|---|---|---|
| Syntax and composition | 400 | 2 | 0 | 0 |
| Representation events | 308 | 0 | 0 | 94 |
| JSON projection | 277 | 2 | 0 | 123 |
out.yaml projection |
241 | 0 | 0 | 161 |
| Emit and round trip | 306 | 0 | 0 | 96 |
All 94 fixtures marked invalid are rejected. The valid 2JQS and X38W
inputs are syntactically recognized and produce matching representation
events, then are rejected during load validation because representation
mapping keys must be unique. They are not unsupported grammar.
The two JSON projection differences are 565N, where !!binary intentionally
becomes byte[] instead of a Base64 string, and J7PZ, where legacy !!omap
intentionally becomes System.Collections.Specialized.OrderedDictionary
instead of remaining a sequence of one-entry mappings. No event mismatch is
classified as policy. The deterministic runner reports no unexplained
failures.
These results are a pinned compatibility measurement, not a claim that a finite corpus proves complete YAML 1.2.2 compliance.
The module preserves data values and graph sharing where representable. A PowerShell object does not retain YAML presentation details, so data round trips do not preserve comments, scalar style, tag spelling or handles, anchor names, mapping presentation, line endings, or source formatting. Unknown application tags are not reconstructed.
Exact integer CLR widths and enum CLR types are not reconstructed after a YAML
round trip. Finite non-exponent decimal values are constructed as Decimal
when representable; other finite floats use Double. The emitter writes a
deliberately limited YAML 1.2-compatible subset.
See CONTRIBUTING.md.