Update module version to 1.1.0 and enhance Merge-DSCConfigurationData function to prevent modifications to sealed parameters

This commit is contained in:
Torsten Brendgen
2026-07-07 21:50:47 +02:00
parent edf7c8ad34
commit 793c4acddd
4 changed files with 85 additions and 4 deletions

View File

@@ -1,6 +1,6 @@
@{
RootModule = "Merge-DSCConfigurationData.psm1"
ModuleVersion = "1.0.2"
ModuleVersion = "1.1.0"
GUID = "c1c7e70d-9049-4eaa-a3c9-44a424c35ef5"
Author = "Torsten Brendgen"
Copyright = "(c) Torsten Brendgen. All rights reserved."

View File

@@ -0,0 +1,14 @@
function Test-ConfigurationDataNodeSealed {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[System.Collections.IDictionary]
$Node
)
if(-not (Test-ConfigurationDataDictionaryKey -Dictionary $Node -Key "Sealed")){
return $false
}
return [System.Management.Automation.LanguagePrimitives]::ConvertTo($Node["Sealed"], [bool])
}

View File

@@ -20,7 +20,11 @@ function Merge-DSCConfigurationData {
[Parameter(Mandatory=$false, ParameterSetName="Path")]
[switch]
$PassThru
$PassThru,
[Parameter(Mandatory=$false, ParameterSetName="Data")]
[string]
$MergePath = '$'
)
begin {
@@ -37,6 +41,10 @@ function Merge-DSCConfigurationData {
$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"
@@ -47,7 +55,7 @@ function Merge-DSCConfigurationData {
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]
$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]))
@@ -89,7 +97,7 @@ function Merge-DSCConfigurationData {
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
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){

View File

@@ -347,4 +347,63 @@ Describe 'Merge-DSCConfigurationData Extends' {
$Validation.IsStale | Should Be $true
@($Validation.Issues | Where-Object { $_.Code -eq 'SourceChanged' }).Count | Should Be 1
}
It 'prevents overriding a sealed parameter definition' {
$Template = @{
Parameters = @{
DomainNetBIOS = @{
Type = 'string'
Value = 'CONTOSO'
Sealed = $true
}
}
}
$Deployment = @{
Parameters = @{
DomainNetBIOS = @{
Value = 'OTHER'
}
}
}
{ Merge-DSCConfigurationData -Template $Template -Deployment $Deployment } | Should Throw
}
It 'prevents adding values below a sealed resource tree' {
$Template = @{
Resources = @{
NonNodeData = @{
Services = @{
SharePoint = @{
Farm = @{
ManagedAccounts = @{
Sealed = $true
FarmAccount = "[parameters('FarmCredential')]"
}
}
}
}
}
}
}
$Deployment = @{
Resources = @{
NonNodeData = @{
Services = @{
SharePoint = @{
Farm = @{
ManagedAccounts = @{
SearchAccount = "[parameters('SearchCredential')]"
}
}
}
}
}
}
}
{ Merge-DSCConfigurationData -Template $Template -Deployment $Deployment } | Should Throw
}
}