Private/Parse-CloudVmTemplateText.ps1

function Parse-CloudVMTemplateText {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$TemplateText,
        
        [Parameter(Mandatory=$false)]
        [string]$Section
    )
    
    # If a specific section is requested
    if ($PSBoundParameters.ContainsKey('Section')) {
        # Pattern to match: SECTION = [ ... ]
        $pattern = "(?ms)$Section\s*=\s*\[\s*([^\]]+)\s*\]"
        
        $matches = [regex]::Matches($TemplateText, $pattern)
        
        if ($matches.Count -eq 0) {
            return $null
        }
        
        # Parse each match (handles multiple instances like SNAPSHOT)
        $results = @()
        foreach ($match in $matches) {
            $content = $match.Groups[1].Value
            $properties = @{}
            
            # Split by commas, but be careful with nested values
            $pairs = $content -split ',\s*(?=\w+\s*=)'
            
            foreach ($pair in $pairs) {
                if ($pair -match '^\s*(\w+)\s*=\s*(.+?)\s*$') {
                    $key = $matches[1]
                    $value = $matches[2].Trim().Trim('"')
                    $properties[$key] = $value
                }
            }
            
            $results += [PSCustomObject]$properties
        }
        
        # Return single object or array
        if ($results.Count -eq 1) {
            return $results[0]
        } else {
            return $results
        }
    }
    
    # If no section specified, parse all sections
    $parsed = @{}
    
    # Pattern to match any section: KEYWORD = [ ... ] or KEYWORD = value
    $sectionPattern = '(?ms)^(\w+)\s*=\s*(?:\[\s*([^\]]+)\s*\]|([^\r\n]+))'
    
    $matches = [regex]::Matches($TemplateText, $sectionPattern)
    
    foreach ($match in $matches) {
        $key = $match.Groups[1].Value
        
        if ($match.Groups[2].Success) {
            # It's a bracketed section
            $content = $match.Groups[2].Value
            $properties = @{}
            
            $pairs = $content -split ',\s*(?=\w+\s*=)'
            
            foreach ($pair in $pairs) {
                if ($pair -match '^\s*(\w+)\s*=\s*(.+?)\s*$') {
                    $propKey = $matches[1]
                    $propValue = $matches[2].Trim().Trim('"')
                    $properties[$propKey] = $propValue
                }
            }
            
            # Handle multiple instances of the same key (like SNAPSHOT)
            if ($parsed.ContainsKey($key)) {
                if ($parsed[$key] -isnot [System.Collections.ArrayList]) {
                    $existing = $parsed[$key]
                    $parsed[$key] = [System.Collections.ArrayList]@($existing)
                }
                $parsed[$key].Add([PSCustomObject]$properties) | Out-Null
            } else {
                $parsed[$key] = [PSCustomObject]$properties
            }
        } else {
            # It's a simple key=value
            $value = $match.Groups[3].Value.Trim().Trim('"')
            $parsed[$key] = $value
        }
    }
    
    return [PSCustomObject]$parsed
}