Private/Module/Format-YAMLObject.ps1
Function Format-YAMLObject { <# .Description Format-YAMLObject indexes YAML Object's (Hashtables), by dynamically iterating through each Keys and Arrays to generate a object cached stucture that's used to perform a direct lookup of the object in the future. In each Key/Item it locates, it appends the object adding the _YAMLPath property to the object. The _YAMLPath property, contains a PowerShell string representation of the .NET path to resolve that property. Why? Format-YAMLObject was written to search and set object properties directly without needing to perform multiple recursive searches. It's used by New-VirtualMachine paramters to match the parameter name to the exact .NET object property. What does this look like? Consider the following object structure: $HashTable = @{ Object = @{ Array = @( @{ Property = 'Value' } ) } } To resolve this, in PowerShell would be: $HashTable.Object.Array[0].Property This function performs a similar process: $property = $HashTable."Object"."Array"[0]."Property" $value = 'Test123' Note the double quotes wrapped around the properties. This is to ensure that object's or properties that contains spaces are handled. This string can then be parsed into a PowerShell ScriptBlock to Get/Set the value dynamically. For Example, PowerShell will dynamically set 'Test123' to $HashTable: [ScriptBlock]::Create(('{0} = "{1}"' -f $property, $value)).Invoke() .PARAMETER YAMLObject The Deseralized YAML object as [HashTable]. .PARAMETER YAMLLookupPath Not used .PARAMETER ObjectName A string representation of the Object Name (include '$') .EXAMPLE $FormattedYAMLTemplate | Format-YAML -Property $Global:SRDSC.DatumModule.YAMLSortOrder .SYNOPSIS Iterates through the YAML file and create linking properties to the parent. This is used to create a PowerShell Object property structure when searching for a PowerShell Key/Value #> [CmdletBinding()] param ( [Object]$YAMLObject, [String]$YAMLLookupPath = "", [String]$ObjectName ) # # Format the Parent Path $ParentPath = $( # # Top-Level Object if ([String]::IsNullOrEmpty($YAMLLookupPath)) { # Object name must exist if $YAMLLookupPath is null if ([String]::IsNullOrEmpty($ObjectName)) { Throw "Error... ObjectName, must be defined!" } '${0}' -f $ObjectName } else { '{0}' -f $YAMLLookupPath } ) # Create an HashTable, with property information that contains # object matching infomation that can be used # to construct a lookup string. switch ($YAMLObject) { # # If the YAMLObject is a hashtable, iterate through each of the properties and # prase the object in. {$YAMLObject.GetType().Name -eq 'Hashtable'} { $newYAMLObject = @{} ForEach($Key in $YAMLObject.Keys) { $params = @{ YAMLObject = $YAMLObject[$Key] YAMLLookupPath = '{0}."{1}"' -f $ParentPath, $Key } $newYAMLObject."$Key" = Format-YAMLObject @params } break; } # # If the YAML Object type is an array. # Iterate through each of the items in the array {$YAMLObject.GetType().Name -eq 'List`1'} { $newYAMLObject = @() #$newYAMLObject = [System.Collections.Generic.List[Object]]::new() # # Iterate through each of the index items and call them For($index = 0; $index -ne $YAMLObject.Count; $index++) { $params = @{ YAMLObject = $YAMLObject[$index] YAMLLookupPath = '{0}[{1}]' -f $ParentPath, $index } $newYAMLObject += Format-YAMLObject @params } } # # These are property types. (String, Int, DateTime) default { $newYAMLObject = $YAMLObject $newYAMLObject = $newYAMLObject | Add-Member -MemberType NoteProperty -Name '_YAMLPath' -Value $ParentPath -Force -PassThru } } return $newYAMLObject } |