public/Restore-WpcArrayShapes.ps1

function Restore-WpcArrayShapes {
    param(
        $templateNode,
        $expandedNode
    )

    if ($templateNode -is [System.Collections.IDictionary]) {
        if ($expandedNode -isnot [System.Collections.IDictionary]) {
            return $expandedNode
        }

        $result = [ordered]@{}
        foreach ($key in $expandedNode.Keys) {
            $templateValue = $null
            if ($templateNode.Contains($key)) {
                $templateValue = $templateNode[$key]
            }
            $result[$key] = Restore-WpcArrayShapes -templateNode $templateValue -expandedNode $expandedNode[$key]
        }
        return $result
    }

    $templateIsArray = $templateNode -is [System.Collections.IEnumerable] -and $templateNode -isnot [string]
    if ($templateIsArray) {
        $templateItems = @($templateNode)
        if ($templateItems.Count -eq 0) {
            return @()
        }

        $expandedItems = [System.Collections.Generic.List[object]]::new()
        $expandedNodeIsArray = (
            $expandedNode -is [System.Collections.IEnumerable] -and
            $expandedNode -isnot [string] -and
            $expandedNode -isnot [System.Collections.IDictionary]
        )
        if ($expandedNodeIsArray) {
            foreach ($expandedItem in $expandedNode) {
                $expandedItems.Add($expandedItem)
            }
        } else {
            $expandedItems.Add($expandedNode)
        }

        $result = [System.Collections.Generic.List[object]]::new()
        for ($index = 0; $index -lt $expandedItems.Count; $index++) {
            $templateItem = if ($index -lt $templateItems.Count) {
                $templateItems[$index]
            } else {
                $templateItems[$templateItems.Count - 1]
            }
            $result.Add((Restore-WpcArrayShapes -templateNode $templateItem -expandedNode $expandedItems[$index]))
        }

        return $result.ToArray()
    }

    return $expandedNode
}