Add functions for configuration data handling and extend template merging capabilities

This commit is contained in:
Torsten Brendgen
2026-07-03 10:34:27 +02:00
parent 735bfc9f61
commit fcbe61902f
8 changed files with 408 additions and 76 deletions

View File

@@ -1,98 +1,124 @@
function Merge-DSCConfigurationData {
[CmdletBinding()]
[CmdletBinding(DefaultParameterSetName="Data")]
Param(
[Parameter(Mandatory=$true)]
[System.Collections.Hashtable]
[Parameter(Mandatory=$true, ParameterSetName="Data")]
[System.Collections.IDictionary]
$Template,
[Parameter(Mandatory=$false)]
[System.Collections.Hashtable]
[Parameter(Mandatory=$false, ParameterSetName="Data")]
[System.Collections.IDictionary]
$Deployment = @{},
[Parameter(Mandatory=$false)]
[System.Collections.Hashtable]
$Output
[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
)
if($Output -eq $null){
$Output = $Deployment
begin {
$TemplatePath = @()
}
foreach($Property in $Template.GetEnumerator()){
if($Property.Value -is [System.Collections.Hashtable]){
Write-Verbose "Key [$($Property.Name)] is a Hashtable"
if($null -ne $Deployment.$($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)
}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.Collections.Specialized.OrderedDictionary]){
Write-Verbose "Key [$($Property.Name)] is a Ordered Dictionary"
if($null -ne $Deployment.$($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)
}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 [$($Deployment.$($Property.Name).Count)]"
if($null -ne $Deployment.$($Property.Name)){
Write-Verbose "Array is defined in Deployment"
process {
if($PSCmdlet.ParameterSetName -eq "Path"){
$TemplatePath += @($Path)
return
}
$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
}
if($Output -eq $null){
$Output = $Deployment
}
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]
}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"
$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 = @($Deployment.$($Property.Name) | Where-Object { Test-ConfigurationDataItemHasKeys -Item $_ -KeyNames $SearchKeyNames })
}else{
$MatchingDeploymentItems = @($Deployment.$($Property.Name) | 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 | Out-Null
$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
}
}else{
}
$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){
Write-Verbose "Wildcard item [$(Format-ConfigurationDataMergeKey -Item $TemplateItem.Value -KeyNames $SearchKeyNames)] in [$($Property.Name)] matched no deployment items"
$MatchingDeploymentItems = @($DeploymentArray | Where-Object { Test-ConfigurationDataItemHasKeys -Item $_ -KeyNames $SearchKeyNames })
}else{
Write-Verbose "Pair [$(Format-ConfigurationDataMergeKey -Item $TemplateItem.Value -KeyNames $SearchKeyNames)] not present"
$Output.$($Property.Name) += ,(Copy-ConfigurationDataValue -Value $TemplateItem.Value)
$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 | 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 "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($null -eq $Deployment.$($Property.Name)){
$Output.Add($Property.Name,(Copy-ConfigurationDataValue -Value $Template.($Property.Name)))
}elseif($Deployment.$($Property.Name) -ne $Property.Value){
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
}
}
return $Output
}