Public/Assert-RequiredProperties.ps1
|
function Assert-RequiredProperties { <# .SYNOPSIS Validates that an object has all required properties and none are empty. Throws a descriptive error if any property is missing or blank. .DESCRIPTION Used by consumer repos to validate JSON config entries without duplicating the PS 5.1-compatible Get-Member + IsNullOrWhiteSpace loop. .PARAMETER Object The PSCustomObject to validate (e.g. a single config entry). .PARAMETER Properties Array of property names that must be present and non-empty. .PARAMETER Context String used in error messages to identify the object (e.g. "VM 'ubuntu-01-ci'"). .EXAMPLE Assert-RequiredProperties -Object $vm ` -Properties @('vmName', 'ipAddress') ` -Context "VM '$($vm.vmName)'" #> [CmdletBinding()] param( [Parameter(Mandatory)] [object] $Object, [Parameter(Mandatory)] [string[]] $Properties, [Parameter(Mandatory)] [string] $Context ) # Get-Member -MemberType NoteProperty is the reliable way to enumerate # properties created by ConvertFrom-Json in PS 5.1 and PS 7. $members = (Get-Member -InputObject $Object -MemberType NoteProperty).Name # Collect all errors before throwing so the consumer sees the full picture # in one run rather than fixing one property at a time. $errors = [System.Collections.Generic.List[string]]::new() foreach ($property in $Properties) { if ($members -notcontains $property) { $errors.Add("$Context is missing required property '$property'.") continue } # Scalars (strings, numbers): IsNullOrWhiteSpace after a [string] cast. # Arrays: count, because asking "does this collection have elements?" # is more direct than relying on [string](@()) = "" as a side-effect. # String is excluded from the array branch despite implementing # IEnumerable<char> so that "" still goes through IsNullOrWhiteSpace. $value = $Object.$property $isEmpty = if ($value -is [System.Collections.IEnumerable] -and $value -isnot [string]) { @($value).Count -eq 0 } else { # Numeric properties (e.g. cpuCount) are [int] in PS 5.1; # cast to [string] so IsNullOrWhiteSpace receives the right type. [string]::IsNullOrWhiteSpace([string]$value) } if ($isEmpty) { $errors.Add("$Context has empty required property '$property'.") } } if ($errors.Count -gt 0) { throw ($errors -join [Environment]::NewLine) } } |