From 82fd103590c47e43a677b2bdb14afb38520adb4e Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Tue, 13 Sep 2022 11:37:59 +0200 Subject: [PATCH 1/6] Add CM Hierarchy Setting --- .../DSC_CMHierarchySetting.psm1 | 357 ++++++++++++++++++ .../DSC_CMHierarchySetting.schema.mof | Bin 0 -> 4314 bytes .../en-US/DSC_CMHierarchySetting.strings.psd1 | 7 + 3 files changed, 364 insertions(+) create mode 100644 source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 create mode 100644 source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof create mode 100644 source/DSCResources/DSC_CMHierarchySetting/en-US/DSC_CMHierarchySetting.strings.psd1 diff --git a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 new file mode 100644 index 0000000..bfa3352 --- /dev/null +++ b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 @@ -0,0 +1,357 @@ +$script:dscResourceCommonPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' +$script:configMgrResourcehelper = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\ConfigMgrCBDsc.ResourceHelper' + +Import-Module -Name $script:dscResourceCommonPath +Import-Module -Name $script:configMgrResourcehelper + +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' + +<# + .SYNOPSIS + This will return a hashtable of results. + + .PARAMETER SiteCode + Specifies the site code for Configuration Manager site. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [String] + $SiteCode + ) + + Write-Verbose -Message $script:localizedData.RetrieveSettingValue + Import-ConfigMgrPowerShellModule -SiteCode $SiteCode + Set-Location -Path "$($SiteCode):\" + + $currentSetting = Get-CMHierarchySetting + $preprodSetting = $currentSetting | Where-Object PropertyNames -contains TargetCollectionID + $upgradeSetting = Get-CMHierarchySetting | Where-Object PropertyNames -contains AdvertisementDuration + $allProperties = Get-CimInstance -Namespace "ROOT\SMS\Site_$SiteCode" -ClassName SMS_SCI_SCProperty + [string] $excludeCollectionId = $currentSetting.ExcludedCollectionID + [string] $targetCollectionId = $preprodSetting.TargetCollectionID + + if (-not [string]::IsNullOrWhiteSpace($excludeCollectionId)) + { + $excludeCollectionName = (Get-CMCollection -Id $excludeCollectionId -ErrorAction SilentlyContinue).Name + } + + if (-not [string]::IsNullOrWhiteSpace($targetCollectionId)) + { + $targetCollectionName = (Get-CMCollection -Id $targetCollectionId -ErrorAction SilentlyContinue).Name + } + + return @{ + SiteCode = $SiteCode + AllowPrestage = $upgradeSetting.AllowPrestage + ApprovalMethod = @("ManuallyApproveEachComputer", "AutomaticallyApproveComputersInTrustedDomains", "AutomaticallyApproveAllComputers")[$allProperties.Where({ $_.PropertyName -eq 'Auto Approval' }).Value] + AutoResolveClientConflict = -not ($allProperties.Where({ $_.PropertyName -eq 'Registration HardwareID Conflict Resolution' }).Value -as [bool]) + EnableAutoClientUpgrade = $upgradeSetting.IsProgramEnabled + EnableExclusionCollection = $upgradeSetting.IsUpgradeExclusionEnabled + EnablePreProduction = $preprodSetting.IsAccepted -and $preprodSetting.IsEnabled + EnablePrereleaseFeature = $currentSetting.Props.Where({ $_.PropertyName -eq 'AcceptedBeta' }).Value -as [bool] + ExcludeServer = $upgradeSetting.ExcludeServers + PreferBoundaryGroupManagementPoint = $currentSetting.Props.Where({ $_.PropertyName -eq 'PreferMPInBoundaryWithFastNetwork' }).Value -as [bool] + UseFallbackSite = -not [string]::IsNullOrWhiteSpace($allProperties.Where({ $_.PropertyName -eq 'SiteAssignmentSiteCode' }).Value1) + AutoUpgradeDays = $upgradeSetting.AdvertisementDuration + ExclusionCollectionName = $excludeCollectionName + FallbackSiteCode = $allProperties.Where({ $_.PropertyName -eq 'SiteAssignmentSiteCode' }).Value1 + TargetCollectionName = $targetCollectionName + TelemetryLevel = @("Basic", "Enhanced", "Full")[$currentSetting.Props.Where({ $_.PropertyName -eq 'TelemetryLevel' }).Value - 1] + } +} + +<# + .SYNOPSIS + This will set the desired state. + + .PARAMETER SiteCode + Specifies the site code for Configuration Manager site. + .PARAMETER AllowPrestage + Indicates that prestaging should be allowed. + .PARAMETER ApprovalMethod + Approval method to use. + .PARAMETER AutoResolveClientConflict + Indicates that client conflicts should automatically be resolved. + .PARAMETER EnableAutoClientUpgrade + Indicates that automatic client upgrades should be enabled. + .PARAMETER EnableExclusionCollection + Indicates that an exclusion collection should be enabled. + .PARAMETER EnablePreProduction + Indicates that a preproduction collection should be enabled. + .PARAMETER EnablePrereleaseFeature + Indicates that pre-release features should be enabled. + .PARAMETER ExcludeServer + Indicates that servers are excluded from auto upgrade. + .PARAMETER PreferBoundaryGroupManagementPoint + Indicates that the boundary group management point should be preferred. + .PARAMETER UseFallbackSite + Indicates that fallback site should be used, which needs to be added using the FallbackSiteCode property. + .PARAMETER AutoUpgradeDays + Days interval for Auto Upgrade. + .PARAMETER ExclusionCollectionName + Exclusion collection name. + .PARAMETER FallbackSiteCode + Site code of fallback site. + .PARAMETER TargetCollectionName + Target collection name. + .PARAMETER TelemetryLevel + Level of telemetry to send. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [String] + $SiteCode, + + [Parameter()] + [bool] + $AllowPrestage, + + [Parameter()] + [ValidateSet( "ManuallyApproveEachComputer", "AutomaticallyApproveComputersInTrustedDomains", "AutomaticallyApproveAllComputers")] + [string] + $ApprovalMethod, + + [Parameter()] + [bool] + $AutoResolveClientConflict, + + [Parameter()] + [bool] + $EnableAutoClientUpgrade, + + [Parameter()] + [bool] + $EnableExclusionCollection, + + [Parameter()] + [bool] + $EnablePreProduction, + + [Parameter()] + [bool] + $EnablePrereleaseFeature, + + [Parameter()] + [bool] + $ExcludeServer, + + [Parameter()] + [bool] + $PreferBoundaryGroupManagementPoint, + + [Parameter()] + [bool] + $UseFallbackSite, + + [Parameter()] + [uint32] + $AutoUpgradeDays, + + [Parameter()] + [string] + $ExclusionCollectionName, + + [Parameter()] + [string] + $FallbackSiteCode, + + [Parameter()] + [string] + $TargetCollectionName, + + [Parameter()] + [ValidateSet("Basic", "Enhanced", "Full")] + [string] + $TelemetryLevel + ) + + Import-ConfigMgrPowerShellModule -SiteCode $SiteCode + Set-Location -Path "$($SiteCode):\" + $PSBoundParameters.Remove('SiteCode') + + try + { + if ($UseFallbackSite -xor $FallbackSiteCode) + { + throw ($script:localizedData.SettingPairMismatch -f 'UseFallbackSite', 'FallbackSiteCode') + } + + if ($EnablePreProduction -xor $TargetCollectionName) + { + throw ($script:localizedData.SettingPairMismatch -f 'EnablePreProduction', 'TargetCollectionName') + } + + if ($EnableExclusionCollection -xor $ExclusionCollectionName) + { + throw ($script:localizedData.SettingPairMismatch -f 'EnableExclusionCollection', 'ExclusionCollectionName') + } + + if ($ExcludeServer -and -not $EnableAutoClientUpgrade) + { + $PSBoundParameters.Remove('ExcludeServer') + Write-Verbose -Message ($script:localizedData.IgnoreAutoUpgrade -f 'ExcludeServer') + } + + if ($AutoUpgradeDays -gt 0 -and -not $EnableAutoClientUpgrade) + { + $PSBoundParameters.Remove('AutoUpgradeDays') + Write-Verbose -Message ($script:localizedData.IgnoreAutoUpgrade -f 'AutoUpgradeDays') + } + + Set-CMHierarchySetting @PSBoundParameters + } + catch + { + throw $_ + } + finally + { + Set-Location -Path "$env:temp" + } +} + +<# + .SYNOPSIS + This will test the desired state. + + .PARAMETER SiteCode + Specifies the site code for Configuration Manager site. + .PARAMETER AllowPrestage + Indicates that prestaging should be allowed. + .PARAMETER ApprovalMethod + Approval method to use. + .PARAMETER AutoResolveClientConflict + Indicates that client conflicts should automatically be resolved. + .PARAMETER EnableAutoClientUpgrade + Indicates that automatic client upgrades should be enabled. + .PARAMETER EnableExclusionCollection + Indicates that an exclusion collection should be enabled. + .PARAMETER EnablePreProduction + Indicates that a preproduction collection should be enabled. + .PARAMETER EnablePrereleaseFeature + Indicates that pre-release features should be enabled. + .PARAMETER ExcludeServer + Indicates that servers are excluded from auto upgrade. + .PARAMETER PreferBoundaryGroupManagementPoint + Indicates that the boundary group management point should be preferred. + .PARAMETER UseFallbackSite + Indicates that fallback site should be used, which needs to be added using the FallbackSiteCode property. + .PARAMETER AutoUpgradeDays + Days interval for Auto Upgrade. + .PARAMETER ExclusionCollectionName + Exclusion collection name. + .PARAMETER FallbackSiteCode + Site code of fallback site. + .PARAMETER TargetCollectionName + Target collection name. + .PARAMETER TelemetryLevel + Level of telemetry to send. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [String] + $SiteCode, + + [Parameter()] + [bool] + $AllowPrestage, + + [Parameter()] + [ValidateSet( "ManuallyApproveEachComputer", "AutomaticallyApproveComputersInTrustedDomains", "AutomaticallyApproveAllComputers")] + [string] + $ApprovalMethod, + + [Parameter()] + [bool] + $AutoResolveClientConflict, + + [Parameter()] + [bool] + $EnableAutoClientUpgrade, + + [Parameter()] + [bool] + $EnableExclusionCollection, + + [Parameter()] + [bool] + $EnablePreProduction, + + [Parameter()] + [bool] + $EnablePrereleaseFeature, + + [Parameter()] + [bool] + $ExcludeServer, + + [Parameter()] + [bool] + $PreferBoundaryGroupManagementPoint, + + [Parameter()] + [bool] + $UseFallbackSite, + + [Parameter()] + [uint32] + $AutoUpgradeDays, + + [Parameter()] + [string] + $ExclusionCollectionName, + + [Parameter()] + [string] + $FallbackSiteCode, + + [Parameter()] + [string] + $TargetCollectionName, + + [Parameter()] + [ValidateSet("Basic", "Enhanced", "Full")] + [string] + $TelemetryLevel + ) + + Import-ConfigMgrPowerShellModule -SiteCode $SiteCode + Set-Location -Path "$($SiteCode):\" + $state = Get-TargetResource -SiteCode $SiteCode + $eval = 'AllowPrestage', 'ApprovalMethod', 'AutoResolveClientConflict', 'EnableAutoClientUpgrade', 'EnableExclusionCollection', 'EnablePreProduction', 'EnablePrereleaseFeature', 'ExcludeServer', 'PreferBoundaryGroupManagementPoint', 'UseFallbackSite', 'AutoUpgradeDays', 'ExclusionCollectionName', 'FallbackSiteCode', 'TargetCollectionName', 'TelemetryLevel' + $result = $true + + foreach ($property in $PSBoundParameters.GetEnumerator()) + { + if ($eval -notcontains $property.Key) + { + continue + } + + if ($property.Value -ne $state[$property.Key]) + { + Write-Verbose -Message ($script:localizedData.TestSetting ` + -f $property.Key, $property.Value, $state[$property.key]) + $result = $false + } + } + + Write-Verbose -Message ($script:localizedData.TestState -f $result) + return $result +} + +Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof new file mode 100644 index 0000000000000000000000000000000000000000..917adbb75fde1932acdda4c3b300272f1ec8e920 GIT binary patch literal 4314 zcmd^DOHbQC5T0|T{)ZK(B2m=Gtvx{?Eoz~NR}TnP!FEVgup`HTMu@-O_WNeC@e2dB z@Tsy$oZZ=(`R2X+`TbH}$f@+?QU)@`b0U$X_#R6lvAmKMc`NJkX8E@wtFk6e`k)$v zHkJ@)=dy?MSNP2nJ=vAdx|?D(l|V+IIK*y-XN)r!pjwqPq4Z!W+sPKFdh+8*9GrZB z9^W8q2PZaF|40rXWeVMADmPLIxBBTo&F56UfM%{Jwv;+hEECnuqdt@g_5x@-R3uZJ z%zz`p_aRm?y!9X_)RiIL(gFo{Vm*1Gnhch_9rPVwZvY$6(oStnZtDx1kbkBc(N1+~ zA1i3SD=j(DFU^Q{)K_C*qBgXWA>uCww5hITs+swSx{cJ9m%!=d925@wmv|Dn!LP8O z^(NL5>_ni5LASA_+b{8sq%DFCXh}U2xmGQlMjX9DKM+lV&l$A#)}%#Fly-(ST7Dw8 zu=56}NPUGBMkH-QRCDa)GR(tQSRu9L1+91l9VmrsAuMiuXtODJui?*pJZs>(jdkV( zqol~)&OTK)vu~9LHMrAA$Z=2q3(RNmbvbj2zNCM5;V&O8ZDa7^EMhIQs>qxQ;9ph& zt_6_Hj4Nlc;su(u3Qb68Oxsx#XKI-fg5)W;=hU14U$i{zIgWo@wjX)(ac!d}8k!-%Lx zL3_O0HHq|bRbE$^eb=y>9Kx?fjEw%OCeMf5dI~>T`-_shK}(F0yw*?aaqKb<+0A~J zK?BRw=SE1bxx9W!S~p0EE7fYlIgtIHIuxUuS<8Mq#11m zvVs?N`Lxu;<_DV*y&n5ZExNJL5ZIZo=lBlfCvdZhamKknrftp&b=J7SG{YV@0&R>F zw1Lf+oXGs#7-H2T$10@Fx85`Tiv0SNO*<#>2JM_-R%?!~V@Qv1M=2xn9NXG&3;gDa z%c8+zmNJ+Nb_4Jo$Vs{Hzz?kZ-&ChoA?)I29i#)op<5%G0 zoXChY`!RpnKj>rLDp~RDp2Q4c9W*;O-IVNJ&D^%z38$?QED>XcxooR_)G=D4>F)9G XT*OcMIS0zY2c=+Wq$C literal 0 HcmV?d00001 diff --git a/source/DSCResources/DSC_CMHierarchySetting/en-US/DSC_CMHierarchySetting.strings.psd1 b/source/DSCResources/DSC_CMHierarchySetting/en-US/DSC_CMHierarchySetting.strings.psd1 new file mode 100644 index 0000000..ad9f6fd --- /dev/null +++ b/source/DSCResources/DSC_CMHierarchySetting/en-US/DSC_CMHierarchySetting.strings.psd1 @@ -0,0 +1,7 @@ +ConvertFrom-StringData @' +RetrieveSettingValue = Getting current hierarchy settings. +TestState = Testing current resource state. In desired state: {0}. +TestSetting = {0} expected value: {1} returned {2}. +SettingPairMismatch = If {0} or {1} are used, both properties need to be specified. +IgnoreAutoUpgrade = {0} is configured, but client auto upgrade is not configured. Skipping setting. +'@ From cb40bbc569ab4d6b52871d0ef6339b68db6e614d Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Tue, 13 Sep 2022 14:26:26 +0200 Subject: [PATCH 2/6] Added tests and examples Updated readme --- CHANGELOG.md | 1 + README.md | 27 ++ .../DSC_CMHierarchySetting.psm1 | 16 +- .../DSC_CMHierarchySetting.schema.mof | Bin 4314 -> 4988 bytes .../CMHierarchySettingAutoUpgrade.ps1 | 22 ++ .../CMHierarchySettingFallbackSite.ps1 | 18 ++ tests/Unit/CMHierarchySetting.tests.ps1 | 285 ++++++++++++++++++ 7 files changed, 361 insertions(+), 8 deletions(-) create mode 100644 source/Examples/Resources/CMHierarchySetting/CMHierarchySettingAutoUpgrade.ps1 create mode 100644 source/Examples/Resources/CMHierarchySetting/CMHierarchySettingFallbackSite.ps1 create mode 100644 tests/Unit/CMHierarchySetting.tests.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8907bc9..cb99b9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ version of DSCResource.Common - Added CMClientSettingsStateMessaging resource - Added CMClientSettingsUserDeviceAffinity resource - Added CMSiteConfiguration resource +- Added CMHierarchySetting resource ### Fixed diff --git a/README.md b/README.md index ffa3284..2ccec42 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,7 @@ Please check out common DSC Community [contributing guidelines](https://dsccommu client policy settings for User Device Affinity settings. - **CMSiteConfiguration**: Provides a resource for modifying the site settings. +- **CMHierarchySetting**: Provides a resource to modify hierarchy settings for a site. ### xSccmPreReqs @@ -2201,6 +2202,32 @@ you are using apply and auto correct. - [CMSiteConfiguration_Cas](Source\Examples\Resources\CMSiteConfiguration\CMSiteConfiguration_Cas.ps1) - [CMSiteConfiguration_Primary](Source\Examples\Resources\CMSiteConfiguration\CMSiteConfiguration_Primary.ps1) +### CMHierarchySetting + +- **[string] SiteCode** _(Key)_: Specifies the SiteCode for the Configuration Manager site. +- **[boolean] AllowPrestage** _(Write)_: Indicates that prestaging should be allowed. +- **[string] ApprovalMethod** _(Write)_: Approval method to use. + - Values include: {ManuallyApproveEachComputer | AutomaticallyApproveComputersInTrustedDomains | AutomaticallyApproveAllComputers} +- **[boolean] AutoResolveClientConflict** _(Write)_: Indicates that client conflicts should automatically be resolved. +- **[boolean] EnableAutoClientUpgrade** _(Write)_: Indicates that automatic client upgrades should be enabled. +- **[boolean] EnableExclusionCollection** _(Write)_: Indicates that an exclusion collection should be enabled. Requires use of ExclusionCollectionName parameter. +- **[boolean] EnablePreProduction** _(Write)_: Indicates that a preproduction collection should be enabled. Requires use of TargetCollectionName parameter. +- **[boolean] EnablePrereleaseFeature** _(Write)_: Indicates that pre-release features should be enabled. This is an operation that cannot be reverted. +- **[boolean] ExcludeServer** _(Write)_: Indicates that servers are excluded from auto upgrade. Skipped if EnableAutoClientUpgrade is not used. +- **[boolean] PreferBoundaryGroupManagementPoint** _(Write)_: Indicates that the boundary group management point should be preferred. +- **[boolean] UseFallbackSite** _(Write)_: Indicates that fallback site should be used. Requires use of FallbackSiteCode parameter. +- **[type] AutoUpgradeDays** _(Write)_: Days for Auto Upgrade advertisement. +- **[string] ExclusionCollectionName** _(Write)_: Exclusion collection name. Requires use of EnableExclusionCollection parameter. +- **[string] FallbackSiteCode** _(Write)_: Site code of fallback site. Requires use of UseFallbackSite parameter. +- **[string] TargetCollectionName** _(Write)_: Target preproduction collection name. Requires use of EnablePreProduction parameter. +- **[string] TelemetryLevel** _(Write)_: Level of telemetry to send. + - Values include: { Basic | Enhanced | Full } + +### CMHierarchySetting Examples + +- [CMHierarchySettingAutoUpgrade](source\Examples\Resources\CMHierarchySetting\CMHierarchySettingAutoUpgrade.ps1) +- [CMHierarchySettingFallbackSite](source\Examples\Resources\CMHierarchySetting\CMHierarchySettingFallbackSite.ps1) + ## ReverseDsc Most organizations using this module already have an existing Configuration Manager diff --git a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 index bfa3352..a6ccce2 100644 --- a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 +++ b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 @@ -30,9 +30,9 @@ function Get-TargetResource $currentSetting = Get-CMHierarchySetting $preprodSetting = $currentSetting | Where-Object PropertyNames -contains TargetCollectionID - $upgradeSetting = Get-CMHierarchySetting | Where-Object PropertyNames -contains AdvertisementDuration + $upgradeSetting = $currentSetting | Where-Object PropertyNames -contains AdvertisementDuration $allProperties = Get-CimInstance -Namespace "ROOT\SMS\Site_$SiteCode" -ClassName SMS_SCI_SCProperty - [string] $excludeCollectionId = $currentSetting.ExcludedCollectionID + [string] $excludeCollectionId = $upgradeSetting.ExcludedCollectionID [string] $targetCollectionId = $preprodSetting.TargetCollectionID if (-not [string]::IsNullOrWhiteSpace($excludeCollectionId)) @@ -53,15 +53,15 @@ function Get-TargetResource EnableAutoClientUpgrade = $upgradeSetting.IsProgramEnabled EnableExclusionCollection = $upgradeSetting.IsUpgradeExclusionEnabled EnablePreProduction = $preprodSetting.IsAccepted -and $preprodSetting.IsEnabled - EnablePrereleaseFeature = $currentSetting.Props.Where({ $_.PropertyName -eq 'AcceptedBeta' }).Value -as [bool] + EnablePrereleaseFeature = $allProperties.Where({ $_.PropertyName -eq 'AcceptedBeta' }).Value -as [bool] ExcludeServer = $upgradeSetting.ExcludeServers - PreferBoundaryGroupManagementPoint = $currentSetting.Props.Where({ $_.PropertyName -eq 'PreferMPInBoundaryWithFastNetwork' }).Value -as [bool] + PreferBoundaryGroupManagementPoint = $allProperties.Where({ $_.PropertyName -eq 'PreferMPInBoundaryWithFastNetwork' }).Value -as [bool] UseFallbackSite = -not [string]::IsNullOrWhiteSpace($allProperties.Where({ $_.PropertyName -eq 'SiteAssignmentSiteCode' }).Value1) AutoUpgradeDays = $upgradeSetting.AdvertisementDuration ExclusionCollectionName = $excludeCollectionName FallbackSiteCode = $allProperties.Where({ $_.PropertyName -eq 'SiteAssignmentSiteCode' }).Value1 TargetCollectionName = $targetCollectionName - TelemetryLevel = @("Basic", "Enhanced", "Full")[$currentSetting.Props.Where({ $_.PropertyName -eq 'TelemetryLevel' }).Value - 1] + TelemetryLevel = @("Basic", "Enhanced", "Full")[$allProperties.Where({ $_.PropertyName -eq 'TelemetryLevel' }).Value - 1] } } @@ -180,17 +180,17 @@ function Set-TargetResource try { - if ($UseFallbackSite -xor $FallbackSiteCode) + if ($UseFallbackSite -xor -not [string]::IsNullOrWhiteSpace($FallbackSiteCode)) { throw ($script:localizedData.SettingPairMismatch -f 'UseFallbackSite', 'FallbackSiteCode') } - if ($EnablePreProduction -xor $TargetCollectionName) + if ($EnablePreProduction -xor -not [string]::IsNullOrWhiteSpace( $TargetCollectionName)) { throw ($script:localizedData.SettingPairMismatch -f 'EnablePreProduction', 'TargetCollectionName') } - if ($EnableExclusionCollection -xor $ExclusionCollectionName) + if ($EnableExclusionCollection -xor -not [string]::IsNullOrWhiteSpace($ExclusionCollectionName)) { throw ($script:localizedData.SettingPairMismatch -f 'EnableExclusionCollection', 'ExclusionCollectionName') } diff --git a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof index 917adbb75fde1932acdda4c3b300272f1ec8e920..a4fa6e431a18b412532c717b63368f6d9bc9da83 100644 GIT binary patch delta 615 zcmcbm_(yHS9CmpHh9HJihC+r?hD?ScAgh=`0mv=}vJ@Ed8PX=p^BD>&FcdH(0%a2! za)II{KwLE0kx6>;1WumG2iUI>G$WT^8;==6lMit02vuMRVaNcw0c1afOk~IdyP*JN zAJFa+pm;u5tOTeM#8+TQ2GV&zm=ES9fn5#qMHyI6$>c)LkD>|;!3^0zy#+v+%8&v! zKW*|sHjuv{Ho^1*{SDNixVeVw1f!xJP$B-HxyYxC(_1%q60FmJ&ME?$;s^}T5+GZb zAr$C@bg*Yqz)npBItS`huv1dO0i4HBGC7-fA;DnX$Zm?&{%%Ie$x3{42=4U2dl{d$xpWBlazD@st2i2U?^ZH z0>{8km6IKrq$gYOB^ZNrm4HRdfF|YuRi**e6#;2Sps5i1LV^0yfnp#VQyKIo gU*=ml`5ynK$$gAslm7^$O%CB#0I@d<31u+?0Lf`Oxc~qF diff --git a/source/Examples/Resources/CMHierarchySetting/CMHierarchySettingAutoUpgrade.ps1 b/source/Examples/Resources/CMHierarchySetting/CMHierarchySettingAutoUpgrade.ps1 new file mode 100644 index 0000000..04c2e6c --- /dev/null +++ b/source/Examples/Resources/CMHierarchySetting/CMHierarchySettingAutoUpgrade.ps1 @@ -0,0 +1,22 @@ +<# + .SYNOPSIS + A DSC configuration script to enable automatic client upgrade while + excluding servers and all machines in the collection called 'NoAutoUpgrade'. +#> +Configuration Example +{ + Import-DscResource -ModuleName ConfigMgrCBDsc + + Node localhost + { + CMHierarchySetting ExampleSettings + { + SiteCode = 'Lab' + EnableAutoClientUpgrade = $true + EnableExclusionCollection = $true + ExcludeServer = $true + ExclusionCollectionName = 'NoAutoUpgrade' + AutoUpgradeDays = 7 + } + } +} diff --git a/source/Examples/Resources/CMHierarchySetting/CMHierarchySettingFallbackSite.ps1 b/source/Examples/Resources/CMHierarchySetting/CMHierarchySettingFallbackSite.ps1 new file mode 100644 index 0000000..9142ab2 --- /dev/null +++ b/source/Examples/Resources/CMHierarchySetting/CMHierarchySettingFallbackSite.ps1 @@ -0,0 +1,18 @@ +<# + .SYNOPSIS + A DSC configuration script to enable usage of a fallback site called FB1. +#> +Configuration Example +{ + Import-DscResource -ModuleName ConfigMgrCBDsc + + Node localhost + { + CMHierarchySetting ExampleSettings + { + SiteCode = 'Lab' + UseFallbackSite = $true + FallbackSiteCode = 'FB1' + } + } +} diff --git a/tests/Unit/CMHierarchySetting.tests.ps1 b/tests/Unit/CMHierarchySetting.tests.ps1 new file mode 100644 index 0000000..fe2d0fa --- /dev/null +++ b/tests/Unit/CMHierarchySetting.tests.ps1 @@ -0,0 +1,285 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param () + +$script:dscModuleName = 'ConfigMgrCBDsc' +$script:dscResourceName = 'DSC_CMHierarchySetting' + +function Invoke-TestSetup +{ + try + { + Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + } + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Unit' + + # Import Stub function + $script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\ConfigMgrCBDscStub.psm1') -Force -WarningAction SilentlyContinue +} + +function Invoke-TestCleanup +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} + +Invoke-TestSetup + +# Begin Testing +try +{ + InModuleScope $script:dscResourceName { + + Describe 'ConfigMgrCBDsc - DSC_CMHierarchySetting\Get-TargetResource' -Tag 'GetHier' { + BeforeAll { + $hierarchyReturn = @( + [pscustomobject]@{ + PropertyNames = @('AdvertisementDuration') + AdvertisementDuration = 10 + AllowPrestage = $true + ExcludedCollectionID = 'ExclusionId' + ExcludeServers = $false + IsProgramEnabled = $true + IsUpgradeExclusionEnabled = $true + } + [pscustomobject]@{ + PropertyNames = @('TargetCollectionID') + IsAccepted = $true + IsEnabled = $true + TargetCollectionID = 'PreprodId' + } + ) + + $cimInstanceReturn = @( + [pscustomobject]@{ + PropertyName = 'Auto Approval' + Value = 1 + } + [pscustomobject]@{ + PropertyName = 'Registration HardwareID Conflict Resolution' + Value = 0 + } + [pscustomobject]@{ + PropertyName = 'AcceptedBeta' + Value = 0 + } + [pscustomobject]@{ + PropertyName = 'PreferMPInBoundaryWithFastNetwork' + Value = 0 + } + [pscustomobject]@{ + PropertyName = 'SiteAssignmentSiteCode' + Value1 = 'SI2' + } + [pscustomobject]@{ + PropertyName = 'TelemetryLevel' + Value = 2 + } + ) + + $preprodCollection = @{ + Name = 'Preprod Collection' + } + + $excludedCollection = @{ + Name = 'Exclusion Collection' + } + + Mock -CommandName Import-ConfigMgrPowerShellModule + Mock -CommandName Set-Location + Mock -CommandName Get-CimInstance -MockWith { $cimInstanceReturn } -ParameterFilter { $ClassName -eq 'SMS_SCI_SCProperty' } + } + + Context 'When retrieving Hierarchy Settings' { + + It 'Should return current hierarchy settings' { + Mock -CommandName Get-CMHierarchySetting -MockWith { $hierarchyReturn } + Mock -CommandName Get-CMCollection -MockWith { $preprodCollection } -ParameterFilter { $Id -eq 'PreprodId' } + Mock -CommandName Get-CMCollection -MockWith { $excludedCollection } -ParameterFilter { $Id -eq 'ExclusionId' } + + + $result = Get-TargetResource -SiteCode Lab + $result | Should -BeOfType System.Collections.HashTable + $result.SiteCode | Should -Be -ExpectedValue 'Lab' + $result.AllowPrestage | Should -Be -ExpectedValue $true + $result.ApprovalMethod | Should -Be -ExpectedValue 'AutomaticallyApproveComputersInTrustedDomains' + $result.AutoResolveClientConflict | Should -Be -ExpectedValue $true + $result.EnableAutoClientUpgrade | Should -Be -ExpectedValue $true + $result.EnableExclusionCollection | Should -Be -ExpectedValue $true + $result.EnablePreProduction | Should -Be -ExpectedValue $true + $result.EnablePrereleaseFeature | Should -Be -ExpectedValue $false + $result.ExcludeServer | Should -Be -ExpectedValue $false + $result.PreferBoundaryGroupManagementPoint | Should -Be -ExpectedValue $false + $result.UseFallbackSite | Should -Be -ExpectedValue $true + $result.AutoUpgradeDays | Should -Be -ExpectedValue 10 + $result.ExclusionCollectionName | Should -Be -ExpectedValue 'Exclusion Collection' + $result.FallbackSiteCode | Should -Be -ExpectedValue 'SI2' + $result.TargetCollectionName | Should -Be -ExpectedValue 'Preprod Collection' + $result.TelemetryLevel | Should -Be -ExpectedValue 'Enhanced' + } + + It 'Should call expected commands when reading the hierarchy setting' { + + Get-TargetResource -SiteCode Lab + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 1 -Scope It + Assert-MockCalled Get-CimInstance -Exactly -Times 1 -Scope It + Assert-MockCalled Get-CMHierarchySetting -Exactly -Times 1 -Scope It + } + } + } + + Describe 'ConfigMgrCBDsc - DSC_CMHierarchySetting\Set-TargetResource' -Tag 'Set' { + BeforeAll { + $correctInput = @{ + SiteCode = 'Lab' + AllowPrestage = $true + ApprovalMethod = 'AutomaticallyApproveComputersInTrustedDomains' + AutoResolveClientConflict = $true + EnableAutoClientUpgrade = $true + EnableExclusionCollection = $true + EnablePreProduction = $true + EnablePrereleaseFeature = $true + ExcludeServer = $true + PreferBoundaryGroupManagementPoint = $true + UseFallbackSite = $true + AutoUpgradeDays = 10 + ExclusionCollectionName = 'Exclusions' + FallbackSiteCode = 'FB1' + TargetCollectionName = 'Preprod' + TelemetryLevel = 'Enhanced' + } + + $fallbackMismatch = $correctInput.Clone() + $fallbackMismatch.UseFallbackSite = $false + $exclusionMismatch = $correctInput.Clone() + $exclusionMismatch.Remove('ExclusionCollectionName') + $preprodMismatch = $correctInput.Clone() + $preprodMismatch.Remove('TargetCollectionName') + $ignoreAutoUpgrade = $correctInput.Clone() + $ignoreAutoUpgrade.EnableAutoClientUpgrade = $false + + Mock -CommandName Set-CMHierarchySetting + Mock -CommandName Import-ConfigMgrPowerShellModule + Mock -CommandName Set-Location + Mock -CommandName Write-Verbose -MockWith {} -ParameterFilter { $Message -eq 'ExcludeServer is configured, but client auto upgrade is not configured. Skipping setting.' } + Mock -CommandName Write-Verbose -MockWith {} -ParameterFilter { $Message -eq 'AutoUpgradeDays is configured, but client auto upgrade is not configured. Skipping setting.' } + } + + Context 'When Set-TargetResource runs successfully' { + It 'Should call expected commands during configuration' { + Set-TargetResource @correctInput + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Set-CMHierarchySetting -Exactly -Times 1 -Scope It + } + It 'Should call expected commands during configuration with mismatched auto upgrade settings' { + Set-TargetResource @ignoreAutoUpgrade + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Write-Verbose -Exactly -Times 1 -ParameterFilter { $Message -eq 'ExcludeServer is configured, but client auto upgrade is not configured. Skipping setting.' } + Assert-MockCalled Write-Verbose -Exactly -Times 1 -ParameterFilter { $Message -eq 'AutoUpgradeDays is configured, but client auto upgrade is not configured. Skipping setting.' } + Assert-MockCalled Set-CMHierarchySetting -Exactly -Times 1 -Scope It + } + } + + Context 'When running Set-TargetResource should throw' { + BeforeEach { + $fallbackMismatchMessage = 'If UseFallbackSite or FallbackSiteCode are used, both properties need to be specified.' + $preprodMismatchMessage = 'If EnablePreProduction or TargetCollectionName are used, both properties need to be specified.' + $exclusionMismatchMessage = 'If EnableExclusionCollection or ExclusionCollectionName are used, both properties need to be specified.' + } + + It 'Should throw and call expected commands when setting with mismatched fallback settings' { + { Set-TargetResource @fallbackMismatch } | Should -Throw -ExpectedMessage $fallbackMismatchMessage + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Set-CMHierarchySetting -Exactly -Times 0 -Scope It + } + + It 'Should throw and call expected commands when setting with mismatched exclusion settings' { + { Set-TargetResource @exclusionMismatch } | Should -Throw -ExpectedMessage $exclusionMismatchMessage + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Set-CMHierarchySetting -Exactly -Times 0 -Scope It + } + + It 'Should throw and call expected commands when setting with mismatched preprod settings' { + { Set-TargetResource @preprodMismatch } | Should -Throw -ExpectedMessage $preprodMismatchMessage + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Set-CMHierarchySetting -Exactly -Times 0 -Scope It + } + } + } + + Describe 'ConfigMgrCBDsc - DSC_CMHierarchySetting\Test-TargetResource' -Tag 'Test' { + BeforeAll { + $returnPresentDefault = @{ + SiteCode = 'Lab' + AllowPrestage = $true + ApprovalMethod = 'AutomaticallyApproveComputersInTrustedDomains' + AutoResolveClientConflict = $true + EnableAutoClientUpgrade = $true + EnableExclusionCollection = $true + EnablePreProduction = $true + EnablePrereleaseFeature = $true + ExcludeServer = $true + PreferBoundaryGroupManagementPoint = $true + UseFallbackSite = $true + AutoUpgradeDays = 10 + ExclusionCollectionName = 'Exclusions' + FallbackSiteCode = 'FB1' + TargetCollectionName = 'Preprod' + TelemetryLevel = 'Enhanced' + } + + $inputPresent = $returnPresentDefault.Clone() + $inputMismatch = @{ + SiteCode = 'Lab' + AllowPrestage = $false + ApprovalMethod = 'AutomaticallyApproveAllComputers' + AutoResolveClientConflict = $false + EnableAutoClientUpgrade = $false + EnableExclusionCollection = $false + EnablePreProduction = $false + EnablePrereleaseFeature = $false + ExcludeServer = $false + PreferBoundaryGroupManagementPoint = $false + UseFallbackSite = $false + AutoUpgradeDays = 42 + ExclusionCollectionName = 'NoExclusions' + TargetCollectionName = 'NoPreprod' + TelemetryLevel = 'Full' + } + + Mock -CommandName Set-Location + Mock -CommandName Import-ConfigMgrPowerShellModule + Mock -CommandName Get-TargetResource -MockWith { $returnPresentDefault } + } + + Context 'When running Test-TargetResource' { + + It 'Should return desired result true settings match' { + Test-TargetResource @inputPresent | Should -Be $true + } + + It 'Should return desired result false when there is a settings mismatch' { + Test-TargetResource @inputMismatch | Should -Be $false + } + } + } + } +} +finally +{ + Invoke-TestCleanup +} From f432225bf1110b84391e37cbc0a296968d5c5336 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Wed, 14 Sep 2022 07:45:15 +0200 Subject: [PATCH 3/6] Change encoding to utf8 --- .../DSC_CMHierarchySetting.schema.mof | Bin 4988 -> 2471 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof index a4fa6e431a18b412532c717b63368f6d9bc9da83..ad7bfe8286dfe936ddf3f92dd9d7b86f9b8323d0 100644 GIT binary patch literal 2471 zcmcguO;6iE5WVMDjB)}gME$sx6Xc^sZCXSEJ)jD0){}U}X4l=1v=QRJcgA*1aEz5) z3J8!rJMZnAc{AzU547<94xLxloOIv!-|=_%vPS8e!|C8*|2=$yACs$xOX2Yby^T&{=cxnqb^jGNJs6^wPGup-on|Q2LZOF{ zB1~1lflUw=*5wZd)-2RAI>FH}5k@T0fv2!O(ST`iM5sD;UZDJR^uC63WfCPt$Z#njGs0>$T=AsXn3@Jt#-|cnjzHujXBxJe`r?*Yni0(GR zcb`ja|NoJz(rk5^q=lHRw_PjB8UM-xkM?05*VsrH<@Ny1&*a^XA`&g&X`G z6$!wt26h3X?YTj9j7{V+QOdHM|!Ih0fji1DV<8gFn!Ywfz!IgY?U4b3W zk~p3@Bs-Hz3lt%;WDRo8Qsseu$o4j)nU~8RQW_Uh7-K`xZfkU8(gr1oU5PR-Kn`c< z(NS7Lc32cY!2}l0u7KMR%GT?{^igFQy;4-`=00QoOqDvK#*up?!D)_kI5VEga~n+} z+y<7;#tc^Z6kf4CGpp$Li@ELyXJlYOgdq;nw4BWDA?2*!X-ovBA$uZ-YpAg>;rd%_HU2S>0w_q0|;q9r? zCJD9K%XDaF(ll{e*nGn^YE~i8^q>Js79clz`gBxV?DSbjNm|JxlL{j-p?}9w>)j3f TW=ORvXIqdQ_Pq0a-s$`Ut&MU_ literal 4988 zcmd^DT~8W86ur+)`X44f)kIA{-r6TcX-%s&g7(3f24PWB1iFANG5&SibM9r>FLqtl z^3-fxWaiHOICJm0GyHjcDKF$gYSNdMjPaaHAR#_`GL(V5k_~wyJMwz*w;`LdB~I#) z>OpoO9ju+nG1lMWJ6F`?NIvOoh|y5mas!D5W+!-hSaS`jO}P|WZ!c^+*@sk3zL(PA z?2MmSCDX+@8cQD zFMR97yxzmu5HkTJ29Vob$eko~2U0bHU3f`9hjOQ0IL$cj3ipB04Dp`AYmX)oIak>! z#)$k#?t$|zq$quh5oRPYVN^5BL^f=PZ!tn?s|%vogb%dBu?`S7J;ZDb-COvxJ)Y)h zJ-|3?f>{#RZfnc>X85Lc(1QofgedOue-ZN~_BvTP@xA2!9$~+Hwp7i*;wmDS87s1; z+Sp&R0LR*}%!*4^R4X?ReYIItvaaql+ai|8)|=(DXFyv)X7?U>R`UL=2ZL-(L?ZHn z6*>a5u{V%Cv#1!)u(!0pIb@U~o;irg`Pzv`eU`Acu9(Sqf&A7;$qm*&EeFUf>?LFx zW<)v*mdER~m;D4wA+i ze+PKPkz|dfBmP(THWe@S>4|c6+RpQlwa&;lJ6Jrj^`J=%1KHNMb!zrXhiqckp1=d+ zo3aQt(ZzaN!S=S!KSZXnTUu|mj3@8fNrSz1fM*DMah4;$g%~Se?S>vbj$*0fTNKH9 zP$Xud@-a`!JQ2}{c>R;tcp~XyhCQA##?EQ>+reBzegH+DJ8TutoUHDM|DNVGH{S=3 ztDS<1dDF8Mz2)iL$Fv^Qm;prT3W!V*TSsx5VT8SaVwvh1O8Up_88u@hXp`fCxXCeB_-rF57^~ehmPZ}! z@zcGcp3rOB&fr;qJ7CgZud^yT`_MPjit_gS&? zTrfPyF#gn%pXFt+DbBoAaLCJE;!A(4Mjk&kR5`m;%@pG`zSC!kRZxk0zbw<9n-^bz zEIWOFkq_+n?BA>o{_eq!U^jVIHT#5}QuFTe_R9}%SayGA-{e_ifDv{A8?A%q$*p;} Z Date: Wed, 14 Sep 2022 14:52:14 +0200 Subject: [PATCH 4/6] Enable CMHierarchySetting for ReverseDsc --- .../ConfigMgrCBDsc.ReverseDsc.psm1 | 45 +++++- .../ConfigMgrCBDsc.ReverseDsc.strings.psd1 | 1 + .../Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 | 144 ++++++++++++++++++ 3 files changed, 188 insertions(+), 2 deletions(-) diff --git a/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 b/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 index b240ddd..74cca4c 100644 --- a/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 +++ b/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 @@ -4906,6 +4906,29 @@ Configuration ConfigureSccm } } + if (`$CMHierarchySetting) + { + CMHierarchySetting `$SiteCode + { + SiteCode = `$SiteCode + AllowPrestage = `$CMHierarchySetting.AllowPrestage + ApprovalMethod = `$CMHierarchySetting.ApprovalMethod + AutoResolveClientConflict = `$CMHierarchySetting.AutoResolveClientConflict + EnableAutoClientUpgrade = `$CMHierarchySetting.EnableAutoClientUpgrade + EnableExclusionCollection = `$CMHierarchySetting.EnableExclusionCollection + EnablePreProduction = `$CMHierarchySetting.EnablePreProduction + EnablePrereleaseFeature = `$CMHierarchySetting.EnablePrereleaseFeature + ExcludeServer = `$CMHierarchySetting.ExcludeServer + PreferBoundaryGroupManagementPoint = `$CMHierarchySetting.PreferBoundaryGroupManagementPoint + UseFallbackSite = `$CMHierarchySetting.UseFallbackSite + AutoUpgradeDays = `$CMHierarchySetting.AutoUpgradeDays + ExclusionCollectionName = `$CMHierarchySetting.ExclusionCollectionName + FallbackSiteCode = `$CMHierarchySetting.FallbackSiteCode + TargetCollectionName = `$CMHierarchySetting.TargetCollectionName + TelemetryLevel = `$CMHierarchySetting.TelemetryLevel + } + } + if (`$CMServiceConnectionPoint) { CMServiceConnectionPoint `$(`$CMServiceConnectionPoint.SiteServerName) @@ -11182,7 +11205,7 @@ function Set-ConfigMgrCBDscReverse 'DistributionGroups','DistributionPoint','DistributionPointGroupMembers', 'EmailNotificationComponent','FallbackPoints','ForestDiscovery','HeartbeatDiscovery', 'MaintenanceWindow','ManagementPoint','NetworkDiscovery','PullDistributionPoint', - 'PxeDistributionPoint','ReportingServicesPoint','SecurityScopes','ServiceConnection', + 'PxeDistributionPoint','ReportingServicesPoint','HierarchySetting','SecurityScopes','ServiceConnection', 'SiteMaintenance','SiteSystemServer','SoftwareDistributionComponent','SoftwareupdatePoint', 'StatusReportingComponent','SystemDiscovery','UserDiscovery','ConfigFileOnly','GroupDiscovery', 'SoftwareUpdatePointComponent','ClientSettings','ClientSettingsBits', @@ -11201,7 +11224,7 @@ function Set-ConfigMgrCBDscReverse 'DistributionGroups','DistributionPoint','DistributionPointGroupMembers', 'EmailNotificationComponent','FallbackPoints','ForestDiscovery','HeartbeatDiscovery', 'MaintenanceWindow','ManagementPoint','NetworkDiscovery','PullDistributionPoint', - 'PxeDistributionPoint','ReportingServicesPoint','SecurityScopes','ServiceConnection', + 'PxeDistributionPoint','ReportingServicesPoint', 'HierarchySetting','SecurityScopes','ServiceConnection', 'SiteMaintenance','SiteSystemServer','SoftwareDistributionComponent','SoftwareupdatePoint', 'StatusReportingComponent','SystemDiscovery','UserDiscovery','GroupDiscovery', 'SoftwareUpdatePointComponent','ClientSettings','ClientSettingsBits', @@ -12732,6 +12755,24 @@ function Set-ConfigMgrCBDscReverse } } + if (($Include -eq 'All' -and $Exclude -notcontains 'HierarchySetting') -or ($Include -contains 'HierarchySetting')) + { + $resourceName = 'CMHierarchySetting' + Write-Verbose -Message $script:localizedData.Hierarchy -Verbose + $params = @{ + ResourceName = $resourceName + SiteCode = $SiteCode + Indent = 2 + MultiEntry = $false + Resources = $resources + } + + $hierarchySettings = "$resourceName = @{`r`n" + $testThing = Set-OutFile @params + $hierarchySettings += "$testThing" + $fileOut += "$hierarchySettings`r`n" + } + if (($Include -eq 'All' -and $Exclude -notcontains 'SecurityScopes') -or ($Include -contains 'SecurityScopes')) { $resourceName = 'CMSecurityScopes' diff --git a/source/Modules/ConfigMgrCBDsc.ReverseDsc/en-US/ConfigMgrCBDsc.ReverseDsc.strings.psd1 b/source/Modules/ConfigMgrCBDsc.ReverseDsc/en-US/ConfigMgrCBDsc.ReverseDsc.strings.psd1 index 1ab4ec5..1071772 100644 --- a/source/Modules/ConfigMgrCBDsc.ReverseDsc/en-US/ConfigMgrCBDsc.ReverseDsc.strings.psd1 +++ b/source/Modules/ConfigMgrCBDsc.ReverseDsc/en-US/ConfigMgrCBDsc.ReverseDsc.strings.psd1 @@ -45,4 +45,5 @@ ConvertFrom-StringData @' ClientSoftUp = Processing CMClientSettingsSoftwareUpdate for client policy: {0}. ClientStateMessage = Processing CMClientSettingsStateMessaging for client policy: {0}. ClientAffinity = Processing CMClientSettingsUserDeviceAffinity for client policy: {0}. + Hierarchy = Processing CMHierarchySetting. '@ diff --git a/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 b/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 index b51d14f..1c842cb 100644 --- a/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 +++ b/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 @@ -4291,6 +4291,122 @@ InModuleScope $script:subModuleName { } ) } + @{ + ImplementedAs = 'PowerShell' + Name = 'CMHierarchySetting' + ModuleName = 'ConfigMgrCBDsc' + Version = '1.0.1' + Properties = @( + @{ + Name = 'SiteCode' + PropertyType = '[string]' + IsMandatory = $true + Values = '{}' + } + @{ + Name = 'AllowPrestage' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'ApprovalMethod' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'AutoResolveClientConflict' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'EnableAutoClientUpgrade' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'EnableExclusionCollection' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'EnablePreProduction' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'EnablePrereleaseFeature' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'ExcludeServer' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'PreferBoundaryGroupManagementPoint' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'UseFallbackSite' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'AutoUpgradeDays' + PropertyType = '[UInt32]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'ExclusionCollectionName' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'FallbackSiteCode' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'TargetCollectionName' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'TelemetryLevel' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'DependsOn' + PropertyType = '[string[]]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'PsDscRunAsCredential' + PropertyType = '[PSCredential]' + IsMandatory = $false + Values = '{}' + } + ) + } ) $invokeCMAccounts = @{ @@ -6253,6 +6369,33 @@ InModuleScope $script:subModuleName { SiteSystemCollectionBehavior = 'Block' PSComputerName = 'localhost' } + + $invokeHierarchySetting = @{ + ConfigurationName = $null + DependsOn = $null + ModuleName = 'ConfigMgrCBDsc' + ModuleVersion = 1.0.1 + PsDscRunAsCredential = $null + ResourceId = $null + SourceInfo = $null + AllowPrestage = $true + ApprovalMethod = 'AutomaticallyApproveComputersInTrustedDomains' + AutoResolveClientConflict = $true + EnableAutoClientUpgrade = $true + EnableExclusionCollection = $true + EnablePreProduction = $true + EnablePrereleaseFeature = $true + ExcludeServer = $true + PreferBoundaryGroupManagementPoint = $true + UseFallbackSite = $true + AutoUpgradeDays = 10 + ExclusionCollectionName = 'Exclusions' + FallbackSiteCode = 'FB1' + TargetCollectionName = 'Preprod' + TelemetryLevel = 'Enhanced' + SiteCode = 'LAB' + PSComputerName = 'localhost' + } } Context 'When running the Set-ConfigMgrCBDscReverse' { @@ -6352,6 +6495,7 @@ InModuleScope $script:subModuleName { Mock -CommandName Invoke-DscResource -MockWith { $invokeCMClientSettingsStateMessaging } -ParameterFilter { $Name -eq 'CMClientSettingsStateMessaging' } Mock -CommandName Invoke-DscResource -MockWith { $invokeCMClientSettingsUserDeviceAffinity } -ParameterFilter { $Name -eq 'CMClientSettingsUserDeviceAffinity' } Mock -CommandName Invoke-DscResource -MockWith { $invokeSiteConfigurationCas } -ParameterFilter { $Name -eq 'CMSiteConfiguration' } + Mock -CommandName Invoke-DscResource -MockWith { $invokeHierarchySetting } -ParameterFilter { $Name -eq 'CMHierarchySetting' } $result = Set-ConfigMgrCBDscReverse @testAll $result | Should -BeOfType System.String From 9fad55ea3711d0b911f659f616b97dcc590cb435 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Fri, 16 Sep 2022 08:19:48 +0200 Subject: [PATCH 5/6] CMHierarchySetting code review --- CHANGELOG.md | 3 ++- README.md | 1 + .../DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 | 1 + .../DSC_CMHierarchySetting.schema.mof | 1 - .../en-US/DSC_CMHierarchySetting.strings.psd1 | 6 +++--- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb99b9e..8cd0497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ version of DSCResource.Common - Added CMClientSettingsComputerRestart resource +- Added CMHierarchySetting resource + ## [3.0.0] - 2022-01-03 ### Added @@ -41,7 +43,6 @@ version of DSCResource.Common - Added CMClientSettingsStateMessaging resource - Added CMClientSettingsUserDeviceAffinity resource - Added CMSiteConfiguration resource -- Added CMHierarchySetting resource ### Fixed diff --git a/README.md b/README.md index 2ccec42..3705be3 100644 --- a/README.md +++ b/README.md @@ -2306,6 +2306,7 @@ all of the modules and specify if it is currently supported by ReverseDSC. - DSC_CMForestDiscovery: Fully Supported - DSC_CMGroupDiscovery: Fully Supported - DSC_CMHeartbeatDiscovery: Fully Supported +- DSC_CMHierarchySetting: Fully Supported - DSC_CMIniFile: Not Supported - DSC_CMMaintenanceWindows: Fully Supported - DSC_CMManagementPoint: Fully Supported diff --git a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 index a6ccce2..6bcad81 100644 --- a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 +++ b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.psm1 @@ -355,3 +355,4 @@ function Test-TargetResource } Export-ModuleMember -Function *-TargetResource + diff --git a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof index ad7bfe8..e424a82 100644 --- a/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof +++ b/source/DSCResources/DSC_CMHierarchySetting/DSC_CMHierarchySetting.schema.mof @@ -1,4 +1,3 @@ - [ClassVersion("1.0.0.0"), FriendlyName("CMHierarchySetting")] class DSC_CMHierarchySetting : OMI_BaseResource { diff --git a/source/DSCResources/DSC_CMHierarchySetting/en-US/DSC_CMHierarchySetting.strings.psd1 b/source/DSCResources/DSC_CMHierarchySetting/en-US/DSC_CMHierarchySetting.strings.psd1 index ad9f6fd..6bd115c 100644 --- a/source/DSCResources/DSC_CMHierarchySetting/en-US/DSC_CMHierarchySetting.strings.psd1 +++ b/source/DSCResources/DSC_CMHierarchySetting/en-US/DSC_CMHierarchySetting.strings.psd1 @@ -1,7 +1,7 @@ ConvertFrom-StringData @' RetrieveSettingValue = Getting current hierarchy settings. -TestState = Testing current resource state. In desired state: {0}. +TestState = Testing current resource state. In desired state: {0}. TestSetting = {0} expected value: {1} returned {2}. -SettingPairMismatch = If {0} or {1} are used, both properties need to be specified. -IgnoreAutoUpgrade = {0} is configured, but client auto upgrade is not configured. Skipping setting. +SettingPairMismatch = If {0} or {1} are used, both properties need to be specified. +IgnoreAutoUpgrade = {0} is configured, but client auto upgrade is not configured. Skipping setting. '@ From 0c7b1886870f74d814c16a5d6e70caccaacfdbb1 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Wed, 21 Sep 2022 20:22:56 +0200 Subject: [PATCH 6/6] Fixed ReverseDsc tests --- tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 b/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 index 1c842cb..9d5600b 100644 --- a/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 +++ b/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 @@ -6500,7 +6500,7 @@ InModuleScope $script:subModuleName { $result = Set-ConfigMgrCBDscReverse @testAll $result | Should -BeOfType System.String Assert-MockCalled Get-CMAccount -Exactly -Times 1 -Scope It - Assert-MockCalled Invoke-DscResource -Exactly -Times 48 -Scope It + Assert-MockCalled Invoke-DscResource -Exactly -Times 49 -Scope It Assert-MockCalled Get-CMAdministrativeUser -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMAssetIntelligenceSynchronizationPoint -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMClientSetting -Exactly -Times 20 -Scope It