2

I'm working with powershell-yaml to parse my YAML into a PowerShell object.

currently, I have a problem validating my YAML schema. I've used this package yaml-schema-validator for my javascript project and I couldn't find any familiar function\moudle to help me solve this problem with Powershell.

Is There a schema validation language for YAML in Powershell?

Amit Baranes
  • 7,398
  • 2
  • 31
  • 53

2 Answers2

2

Simply put, no, I don't believe there are any Powershell native options for doc validation against a YAML schema.

Since YAML is a super-set of JSON, one could (depending on the YAML being validated), use a schema expressed in JSON and validated w/Test-JSON.

There are two active YAML modules I'm aware of: (1) PSYaml and (2) powershell-yaml. The second being what you use today. I don't believe either of them validate YAML docs against a schema.

I believe there are schema validation modules/projects in the following:

  • Ruby
  • Python
  • PHP
  • JavaScript

You can see the list in Schema Validation for YAML.

You could always do you validation in another language, and wrap that call in Powershell. You just have to handle the integration yourself.

Adam
  • 3,891
  • 3
  • 19
  • 42
1

Despite the general correct suggestion from @Adam, I have not been able to get this to work with native PowerShell/.Net using the [Newtonsoft.json] classes (see also: Test-Json (validate schema) in Windows PowerShell).

Nevertheless, here is a cumbersome way (converting everything to Json first) to do this in PowerShell 7:

Install-Module powershell-yaml

function Test-Yaml {
    [CmdletBinding(DefaultParameterSetName='__AllParameterSets', HelpUri='https://go.microsoft.com/fwlink/?LinkID=2096609')]
    param(
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [string]
        ${Yaml},

        [Parameter(ParameterSetName='SchemaString', Position=1)]
        [ValidateNotNullOrEmpty()]
        [string]
        ${Schema},

        [Parameter(ParameterSetName='SchemaFile', Position=1)]
        [ValidateNotNullOrEmpty()]
        [string]
        ${SchemaFile})

    begin {
        function Yaml2Json ($Yaml) { $Yaml |ConvertFrom-Yaml |ConvertTo-Json -Depth 64 }
        $outBuffer = $null
        if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) { $PSBoundParameters['OutBuffer'] = 1 }
        $Parameters = @{}
        foreach($PSBoundParameters in $PSBoundParameters.GetEnumerator()) {
            switch ($PSBoundParameters.Key) {
                'Yaml'       { $Parameters['Json']   = Yaml2Json $PSBoundParameters.Value }
                'Schema'     { $Parameters['Schema'] = Yaml2Json $PSBoundParameters.Value }
                'SchemaFile' { $Parameters['Schema'] = Yaml2Json (Get-Content -Raw -LiteralPath $PSBoundParameters.Value) }
                Default      { $Parameters[$PSBoundParameters.Key] = $PSBoundParameters.Value }
            }
        }

        $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\Test-Json', [System.Management.Automation.CommandTypes]::Cmdlet)
        $scriptCmd = { & $wrappedCmd @Parameters }

        $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
        $steppablePipeline.Begin($PSCmdlet)
    }

    process {
        $Json = Yaml2Json $_
        $steppablePipeline.Process($Json)
    }

    end {
        $steppablePipeline.End()
    }

    clean
    {
        if ($null -ne $steppablePipeline) {
            $steppablePipeline.Clean()
        }
    }
}
$YamlSchema = @'
description: A person
type: object
required:
- name
- hobbies
properties:
  name:
    type: string
  hobbies:
    type: array
    items:
      type: string
'@
$Yaml = @'
name: James
hobbies:
- .NET
- Blogging
- Reading
- Xbox
- LOLCATS
'@

$Yaml |Test-Yaml -Schema $YamlSchema
True
$Yaml = @'
test: James
hobbies:
- .NET
- Blogging
- Reading
- Xbox
- LOLCATS
'@

$Yaml |Test-Yaml -Schema $YamlSchema
Test-Json: PropertyRequired: #/name
False
iRon
  • 20,463
  • 10
  • 53
  • 79