function Merge-DSCConfigurationData { [CmdletBinding(DefaultParameterSetName="Data")] Param( [Parameter(Mandatory=$true, ParameterSetName="Data")] [System.Collections.IDictionary] $Template, [Parameter(Mandatory=$false, ParameterSetName="Data")] [System.Collections.IDictionary] $Deployment = @{}, [Parameter(Mandatory=$false, ParameterSetName="Data")] [System.Collections.IDictionary] $Output, [Parameter(Mandatory=$true, ParameterSetName="Path", ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [Alias("FullName")] [string[]] $Path, [Parameter(Mandatory=$false, ParameterSetName="Path")] [switch] $PassThru, [Parameter(Mandatory=$false, ParameterSetName="Data")] [string] $MergePath = '$' ) begin { $TemplatePath = @() } process { if($PSCmdlet.ParameterSetName -eq "Path"){ $TemplatePath += @($Path) return } if($Output -eq $null){ $Output = $Deployment } if((Test-ConfigurationDataNodeSealed -Node $Template) -and $Deployment.Count -gt 0){ throw "Configuration data path [$MergePath] is sealed and cannot be modified." } foreach($Property in $Template.GetEnumerator()){ if($Property.Name -eq "Metadata"){ Write-Verbose "Skipping metadata block during configuration data merge" continue } if($Property.Value -is [System.Collections.IDictionary]){ Write-Verbose "Key [$($Property.Name)] is a Dictionary" if(Test-ConfigurationDataDictionaryKey -Dictionary $Deployment -Key $Property.Name){ Write-Verbose "Key [$($Property.Name)] is present in Deployment Data" $Output[$Property.Name] = Merge-DSCConfigurationData -Template $Template[$Property.Name] -Deployment $Deployment[$Property.Name] -Output $Output[$Property.Name] -MergePath "$MergePath.$($Property.Name)" }else{ Write-Verbose "Key [$($Property.Name)] is not present in Deployment Data" $Output.Add($Property.Name,(Copy-ConfigurationDataValue -Value $Template[$Property.Name])) } }elseif($Property.Value -is [System.Array]){ Write-Verbose "$($Property.Name) is ein Array" Write-Verbose "Total Items in Template Array [$($Property.Value.Count)]" Write-Verbose "Total Items in Deployment Array [$(@(Get-ConfigurationDataDictionaryValue -Dictionary $Deployment -Key $Property.Name -DefaultValue @()).Count)]" if(Test-ConfigurationDataDictionaryKey -Dictionary $Deployment -Key $Property.Name){ Write-Verbose "Array is defined in Deployment" $DeploymentArray = Get-ConfigurationDataDictionaryValue -Dictionary $Deployment -Key $Property.Name $TemplateItems = for($i=0;$i -lt $Property.Value.Count; $i++){ $SearchKeyNames = @(Get-ConfigurationDataArrayMergeKeyNames -ArrayName $Property.Name -Item $Property.Value[$i]) [PSCustomObject]@{ Value = $Property.Value[$i] SearchKeyNames = $SearchKeyNames IsWildcard = Test-ConfigurationDataItemWildcard -Item $Property.Value[$i] -KeyNames $SearchKeyNames } } $TemplateItems = @($TemplateItems | Where-Object { -not $_.IsWildcard }) + @($TemplateItems | Where-Object { $_.IsWildcard }) foreach($TemplateItem in $TemplateItems){ $SearchKeyNames = @($TemplateItem.SearchKeyNames) if($SearchKeyNames.Count -eq 0){ Write-Verbose "No matching name key found for item in [$($Property.Name)]" $Output[$Property.Name] += ,(Copy-ConfigurationDataValue -Value $TemplateItem.Value) continue } if($TemplateItem.IsWildcard){ $MatchingDeploymentItems = @($DeploymentArray | Where-Object { Test-ConfigurationDataItemHasKeys -Item $_ -KeyNames $SearchKeyNames }) }else{ $MatchingDeploymentItems = @($DeploymentArray | Where-Object { Test-ConfigurationDataItemKeyMatch -Left $_ -Right $TemplateItem.Value -KeyNames $SearchKeyNames }) } if($MatchingDeploymentItems.Count -gt 0){ foreach($DeploymentItem in $MatchingDeploymentItems){ $OutputItem = @($Output[$Property.Name] | Where-Object { Test-ConfigurationDataItemKeyMatch -Left $_ -Right $DeploymentItem -KeyNames $SearchKeyNames })[0] Merge-DSCConfigurationData -Template $TemplateItem.Value -Deployment $DeploymentItem -Output $OutputItem -MergePath "$MergePath.$($Property.Name)[$(Format-ConfigurationDataMergeKey -Item $DeploymentItem -KeyNames $SearchKeyNames)]" | Out-Null } }else{ if($TemplateItem.IsWildcard){ Write-Verbose "Wildcard item [$(Format-ConfigurationDataMergeKey -Item $TemplateItem.Value -KeyNames $SearchKeyNames)] in [$($Property.Name)] matched no deployment items" }else{ Write-Verbose "Pair [$(Format-ConfigurationDataMergeKey -Item $TemplateItem.Value -KeyNames $SearchKeyNames)] not present" $Output[$Property.Name] += ,(Copy-ConfigurationDataValue -Value $TemplateItem.Value) } } } }else{ Write-Verbose "Array is not defined in Deployment" $Output[$Property.Name] = Copy-ConfigurationDataValue -Value $Template[$Property.Name] } }else{ Write-Verbose "$($Property.Name) is a String or Integer Value" if(-not (Test-ConfigurationDataDictionaryKey -Dictionary $Deployment -Key $Property.Name)){ $Output.Add($Property.Name,(Copy-ConfigurationDataValue -Value $Template[$Property.Name])) }elseif($Deployment[$Property.Name] -ne $Property.Value){ } } } return $Output } end { if($PSCmdlet.ParameterSetName -eq "Path"){ return Merge-ConfigurationDataTemplateFile -Path $TemplatePath -PassThru:$PassThru } } }