diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ffb9e2..249490b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added ConfigMgrCBDsc.ReverseDsc module - Added CMEmailNotificationComponent +- Added CMGroupDiscovery Resource ### Fixed diff --git a/README.md b/README.md index a0b521a..09c2ca9 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,8 @@ Please check out common DSC Community [contributing guidelines](https://dsccommu file replication settings in Configuration Manager. - **CMEmailNotificationComponent**: Provides a resource for modifying email notification component settings. +- **CMGroupDiscovery**: Provides a resource to manage the Configuration Manager + Group Discovery method. ### xSccmPreReqs @@ -1361,6 +1363,61 @@ you are using apply and auto correct. - [CMEmailNotificationComponent_Present](Source\Examples\Resources\CMEmailNotificationComponent\CMEmailNotificationComponent_Present.ps1) - [CMEmailNotificationComponent_Absent](Source\Examples\Resources\CMEmailNotificationComponent\CMEmailNotificationComponent_Absent.ps1) +### CMGroupDiscovery + +- **[String] SiteCode** _(Key)_: Specifies the Site Code for the Configuration + Manager site. +- **[Boolean] Enabled** _(Key)_: Specifies the enablement of the system discovery + method. +- **[Boolean] EnableDeltaDiscovery** _(Write)_: Indicates whether Configuration Manager + discovers resources created or modified in AD DS since the last discovery cycle. +- **[UInt32] DeltaDiscoveryMins** _(Write)_: Specifies the number of minutes for + the delta discovery. + - Values Range: 5 - 60 +- **[Boolean] EnableFilteringExpiredLogon** _(Write)_: Indicates whether Configuration + Manager discovers only computers that have logged onto a domain within a specified + number of days. +- **[UInt32] TimeSinceLastLogonDays** _(Write)_: Specify the number of days for + EnableFilteringExpiredLogon. + - Values Range: 14 - 720 +- **[Boolean] EnableFilteringExpiredPassword** _(Write)_: Indicates whether Configuration + Manager discovers only computers that have updated their computer account password + within a specified number of days. +- **[UInt32] TimeSinceLastPasswordUpdateDays** _(Write)_: Specify the number of days + for EnableFilteringExpiredPassword. + - Values Range: 30 - 720 +- **[EmbeddedInstance] GroupDiscoveryScope[]** _(Write)_: Specifies an array of Group + Discovery Scopes to match to the discovery. +- **[EmbeddedInstance] GroupDiscoveryScopeToInclude[]** _(Write)_: Specifies an array + of Group Discovery Scopes to add to the discovery. +- **[String] GroupDiscoveryScopeToExclude[]** _(Write)_: Specifies an array of names + of Group Discovery Scopes to exclude to the discovery. +- **[Boolean] DiscoverDistributionGroupMembership** _(Write)_: Specify if group discovery + will discover distribution groups and the members of the group. +- **[String] Start** _(Write)_: Specifies the start date and start time for the + collection refresh schedule Month/Day/Year, example 1/1/2020 02:00. +- **[String] ScheduleType** _(Write)_: Specifies the schedule type for the collection + refresh schedule. + - Values include: { MonthlyByDay | MonthlyByWeek | Weekly | Days | Hours | + Minutes | None } +- **[UInt32] RecurInterval** _(Write)_: Specifies how often the ScheduleType is run. +- **[String] MonthlyWeekOrder** _(Write)_: Specifies week order for MonthlyByWeek + schedule type. + - Values include: { First | Second | Third | Fourth | Last } +- **[String] DayOfWeek** _(Write)_: Specifies the day of week name for MonthlyByWeek + and Weekly schedules. + - Values include: { Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | + Saturday } +- **[UInt32] DayOfMonth** _(Write)_: Specifies the day number for MonthlyByDay schedules. + Note specifying 0 sets the schedule to run the last day of the month. + - Values Range: 0 - 31 + +#### CMGroupDiscovery Examples + +- [GroupDiscovery_Enabled](Source\Examples\Resources\CMGroupDiscovery\GroupDiscovery_Enabled.ps1) +- [GroupDiscovery_Include_Exclude](Source\Examples\Resources\CMGroupDiscovery\GroupDiscovery_Include_Exclude.ps1) +- [GroupDiscovery_Disabled](Source\Examples\Resources\CMGroupDiscovery\GroupDiscovery_Disabled.ps1) + ## ReverseDsc Most organizations using this module already have an existing Configuration Manager @@ -1417,6 +1474,7 @@ all of the modules and specify if it is currently supported by ReverseDSC. - DSC_CMFallbackStatusPoint: Fully Supported - DSC_CMFileReplication: Not Supported - DSC_CMForestDiscovery: Fully Supported +- DSC_CMGroupDiscovery: Fully Supported - DSC_CMHeartbeatDiscovery: Fully Supported - DSC_CMIniFile: Not Supported - DSC_CMMaintenanceWindows: Fully Supported @@ -1462,9 +1520,9 @@ After importing the module, Set-ConfigMgrCBDscReverse will be available. ClientPush|ClientStatusSettings|CollectionEvaluationComponent|Collections| DistributionGroups|DistributionPoint|DistributionPointGroupMembers|EmailNotificationComponent| FallbackPoints|ForestDiscovery|HeartbeatDiscovery|MaintenanceWindow|ManagementPoint| - NetworkDiscovery|PullDistributionPoint|PxeDistributionPoint| + NetworkDiscovery|PullDistributionPoint|PxeDistributionPoint|GroupDiscovery| ReportingServicesPoint|SecurityScopes|ServiceConnection|SiteMaintenance| - SiteSystemServer|SoftwareDistributionComponent|SoftwareupdatePoint| + SiteSystemServer|SoftwareDistributionComponent|SoftwareUpdatePoint| StatusReportingComponent|SystemDiscovery|UserDiscovery|ConfigFileOnly } - **[String] Exclude** _(Write)_: Specifies which resources will be excluded from being evaluated. Only evaluated when Include = 'All' @@ -1472,9 +1530,9 @@ After importing the module, Set-ConfigMgrCBDscReverse will be available. ClientPush|ClientStatusSettings|CollectionEvaluationComponent|Collections| DistributionGroups|DistributionPoint|DistributionPointGroupMembers|EmailNotificationComponent| FallbackPoints|ForestDiscovery|HeartbeatDiscovery|MaintenanceWindow|ManagementPoint| - NetworkDiscovery|PullDistributionPoint|PxeDistributionPoint| + NetworkDiscovery|PullDistributionPoint|PxeDistributionPoint|GroupDiscovery| ReportingServicesPoint|SecurityScopes|ServiceConnection|SiteMaintenance| - SiteSystemServer|SoftwareDistributionComponent|SoftwareupdatePoint| + SiteSystemServer|SoftwareDistributionComponent|SoftwareUpdatePoint| StatusReportingComponent|SystemDiscovery|UserDiscovery } - **[String] DataFile** _(Write)_: Specifies where the data file will be saved. Filename must end with .psd1. Not specifying DataFile the output will be displayed diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7b5faea..45f4300 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -22,7 +22,7 @@ stages: - job: Package_Module displayName: 'Package Module' pool: - vmImage: 'ubuntu 16.04' + vmImage: 'ubuntu 18.04' steps: - task: GitVersion@5 name: gitVersion @@ -154,7 +154,7 @@ stages: displayName: 'Publish Code Coverage' dependsOn: Test_Unit pool: - vmImage: 'ubuntu 16.04' + vmImage: 'ubuntu 18.04' timeoutInMinutes: 0 steps: - pwsh: | @@ -204,7 +204,7 @@ stages: - job: Deploy_Module displayName: 'Deploy Module' pool: - vmImage: 'ubuntu 16.04' + vmImage: 'ubuntu 18.04' steps: - task: DownloadBuildArtifacts@0 displayName: 'Download Build Artifact' diff --git a/source/ConfigMgrCBDsc.psd1 b/source/ConfigMgrCBDsc.psd1 index f5ba66d..f3f172a 100644 --- a/source/ConfigMgrCBDsc.psd1 +++ b/source/ConfigMgrCBDsc.psd1 @@ -80,6 +80,7 @@ 'CMMaintenanceWindows' 'CMFileReplication' 'CMEmailNotificationComponent' + 'CMGroupDiscovery' ) <# @@ -98,7 +99,7 @@ 'ServiceConnectionPoint','NetworkDiscovery','ReportingServicePoint','SystemDiscovery','PXEDistributionPoint','PullDistributionPoint', 'SiteMaintenance','AdministrativeUser','DistributionGroup','SiteSystemServer','StatusReportingComponent','CollectionMembershipEvaluationComponent', 'DistributionPointGroupMembers','SecurityScopes','UserDiscovery','SecurityRoles','ClientPushSettings','SoftwareDistributionComponent', - 'MaintenanceWindows','FileReplication','EmailNotificationComponent') + 'MaintenanceWindows','FileReplication','EmailNotificationComponent','CMGroupDiscovery') # A URL to the license for this module. LicenseUri = 'https://github.com/dsccommunity/ConfigMgrCBDsc/blob/master/LICENSE' diff --git a/source/DSCResources/DSC_CMGroupDiscovery/DSC_CMGroupDiscovery.psm1 b/source/DSCResources/DSC_CMGroupDiscovery/DSC_CMGroupDiscovery.psm1 new file mode 100644 index 0000000..11ccb29 --- /dev/null +++ b/source/DSCResources/DSC_CMGroupDiscovery/DSC_CMGroupDiscovery.psm1 @@ -0,0 +1,815 @@ +$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. + + .PARAMETER Enabled + Specifies the enablement of the Group discovery method. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [String] + $SiteCode, + + [Parameter(Mandatory = $true)] + [Boolean] + $Enabled + ) + + Write-Verbose -Message $script:localizedData.RetrieveSettingValue + Import-ConfigMgrPowerShellModule -SiteCode $SiteCode + Set-Location -Path "$($SiteCode):\" + + $groupDiscovery = Get-CMDiscoveryMethod -Name ActiveDirectoryGroupDiscovery -SiteCode $SiteCode + + if ($groupDiscovery) + { + $adContainers = ($groupDiscovery.Proplists | Where-Object -FilterScript {$_.PropertyListName -eq 'AD Containers'}).Values + $count = 0 + + if ($adContainers) + { + $adGroups = @() + foreach ($item in $adContainers) + { + if ($item -ne 0 -and $item -ne 1) + { + $value = $count + 2 + if ($adContainers[$value] -eq 0) + { + $recurse = $true + } + else + { + $recurse = $false + } + + $ou = ($groupDiscovery.Proplists | Where-Object -FilterScript {$_.PropertyListName -eq "Search Bases:$item"}).Values + $adCollection = @{ + Name = $item + Recurse = $recurse + LDAPLocation = $ou[0] + } + $adGroups += ConvertTo-AnyCimInstance -ClassName DSC_CMGroupDiscoveryScope -Hashtable $adCollection + } + $count ++ + } + } + + $status = ($groupDiscovery.Props | Where-Object -FilterScript {$_.PropertyName -eq 'Settings'}).Value1 + + if ($status -eq 'Active') + { + foreach ($prop in $groupDiscovery.Props) + { + switch ($prop.PropertyName) + { + 'Settings' { $enabledStatus = ($prop.Value1 -eq 'Active') } + 'Full Sync Schedule' { $groupSchedule = $prop.Value1 } + 'Enable Incremental Sync' { [boolean]$deltaEnabled = $prop.Value } + 'Startup Schedule' { $groupDelta = $prop.Value1 } + 'Enable Filtering Expired Logon' { [boolean]$lastLogonEnabled = $prop.Value } + 'Days Since Last Logon' { $lastLogon = $prop.Value } + 'Enable Filtering Expired Password' { [boolean]$lastPasswordEnabled = $prop.Value } + 'Days Since Last Password Set' { $lastPassword = $prop.Value } + 'Discover DG Membership' { [boolean]$dgMemberEnabled = $prop.Value } + } + } + + if ($deltaEnabled -eq $false) + { + $groupSchedule = $groupDelta + $groupDelta = $null + } + + $schedule = Get-CMSchedule -ScheduleString $groupSchedule + + if (-not [string]::IsNullOrEmpty($groupDelta)) + { + $sDelta = Convert-CMSchedule -ScheduleString $groupDelta + + if ($sDelta.HourSpan -eq 1) + { + $syncDelta = 60 + } + else + { + $syncDelta = $sDelta.MinuteSpan + } + } + } + else + { + $enabledStatus = $false + } + } + + return @{ + SiteCode = $SiteCode + Enabled = $enabledStatus + EnableDeltaDiscovery = $deltaEnabled + DeltaDiscoveryMins = $syncDelta + EnableFilteringExpiredLogon = $lastLogonEnabled + TimeSinceLastLogonDays = $lastLogon + EnableFilteringExpiredPassword = $lastPasswordEnabled + TimeSinceLastPasswordUpdateDays = $lastPassword + DiscoverDistributionGroupMembership = $dgMemberEnabled + GroupDiscoveryScope = $adGroups + Start = $schedule.Start + ScheduleType = $schedule.ScheduleType + DayOfWeek = $schedule.DayofWeek + MonthlyWeekOrder = $schedule.WeekOrder + DayofMonth = $schedule.MonthDay + RecurInterval = $schedule.RecurInterval + } +} + +<# + .SYNOPSIS + This will set the desired state. + + .PARAMETER SiteCode + Specifies the site code for Configuration Manager site. + + .PARAMETER Enabled + Specifies the enablement of the group discovery method. + + .PARAMETER EnableDeltaDiscovery + Indicates whether Configuration Manager discovers resources created or modified in AD DS + since the last discovery cycle. If you specify a value of $True for this parameter, + specify a value for the DeltaDiscoveryMins parameter. + + .PARAMETER DeltaDiscoveryMins + Specifies the number of minutes for the delta discovery. + + .PARAMETER EnableFilteringExpiredLogon + Indicates whether Configuration Manager discovers only computers that have logged onto a + domain within a specified number of days. Specify the number of days by using the + TimeSinceLastLogonDays parameter. + + .PARAMETER TimeSinceLastLogonDays + Specify the number of days for EnableFilteringExpiredLogon. + + .PARAMETER EnableFilteringExpiredPassword + Indicates whether Configuration Manager discovers only computers that have updated ther + account password within a specified number of days. Specify the number of days by using the + TimeSinceLastPasswordUpdateDays parameter. + + .PARAMETER TimeSinceLastPasswordUpdateDays + Specify the number of days for EnableFilteringExpiredPassword. + + .PARAMETER DiscoverDistributionGroupMembership + Specify if group discovery will discover distribution groups and the members of the group. + + .PARAMETER GroupDiscoveryScope + Specifies an array of Group Discovery Scopes to match to the discovery. + + .PARAMETER GroupDiscoveryScopeToInclude + Specifies an array of Group Discovery Scopes to add to the discovery. + + .PARAMETER GroupDiscoveryScopeToExclude + Specifies an array of names of Group Discovery Scopes to exclude to the discovery. + + .PARAMETER Start + Specifies the start date and start time for the group discovery schedule Month/Day/Year, example 1/1/2020 02:00. + + .PARAMETER ScheduleType + Specifies the schedule type for the group discovery schedule. + + .PARAMETER RecurInterval + Specifies how often the ScheduleType is run. + + .PARAMETER MonthlyByWeek + Specifies week order for MonthlyByWeek schedule type. + + .PARAMETER DayOfWeek + Specifies the day of week name for MonthlyByWeek and Weekly schedules. + + .PARAMETER DayOfMonth + Specifies the day number for MonthlyByDay schedules. + Note specifying 0 sets the schedule to run the last day of the month. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [String] + $SiteCode, + + [Parameter(Mandatory = $true)] + [Boolean] + $Enabled, + + [Parameter()] + [Boolean] + $EnableDeltaDiscovery, + + [Parameter()] + [ValidateRange(5,60)] + [UInt32] + $DeltaDiscoveryMins, + + [Parameter()] + [Boolean] + $EnableFilteringExpiredLogon, + + [Parameter()] + [ValidateRange(14,720)] + [UInt32] + $TimeSinceLastLogonDays, + + [Parameter()] + [Boolean] + $EnableFilteringExpiredPassword, + + [Parameter()] + [ValidateRange(30,720)] + [UInt32] + $TimeSinceLastPasswordUpdateDays, + + [Parameter()] + [Boolean] + $DiscoverDistributionGroupMembership, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $GroupDiscoveryScope, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $GroupDiscoveryScopeToInclude, + + [Parameter()] + [String[]] + $GroupDiscoveryScopeToExclude, + + [Parameter()] + [String] + $Start, + + [Parameter()] + [ValidateSet('MonthlyByDay','MonthlyByWeek','Weekly','Days','Hours','Minutes','None')] + [String] + $ScheduleType, + + [Parameter()] + [UInt32] + $RecurInterval, + + [Parameter()] + [ValidateSet('First','Second','Third','Fourth','Last')] + [String] + $MonthlyWeekOrder, + + [Parameter()] + [ValidateSet('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')] + [String] + $DayOfWeek, + + [Parameter()] + [ValidateRange(0,31)] + [UInt32] + $DayOfMonth + ) + + Import-ConfigMgrPowerShellModule -SiteCode $SiteCode + Set-Location -Path "$($SiteCode):\" + + try + { + $state = Get-TargetResource -SiteCode $SiteCode -Enabled $Enabled + + if ($Enabled -eq $true) + { + if (($PSBoundParameters.ContainsKey('DeltaDiscoveryMins')) -and ($EnableDeltaDiscovery -eq $false -or + $state.EnableDeltaDiscovery -eq $false)) + { + throw $script:localizedData.MissingDeltaDiscovery + } + + if (($EnableDeltaDiscovery -eq $true -and $state.EnableDeltaDiscovery -eq $false) -and + (-not $PSBoundParameters.ContainsKey('DeltaDiscoveryMins'))) + { + throw $script:localizedData.DeltaNoInterval + } + + if ($PSBoundParameters.ContainsKey('GroupDiscoveryScope')) + { + if ($PSBoundParameters.ContainsKey('GroupDiscoveryScopeToInclude') -or + $PSBoundParameters.ContainsKey('GroupDiscoveryScopeToExclude')) + { + Write-Warning -Message $script:localizedData.GdsIgnore + } + } + elseif ($GroupDiscoveryScopeToInclude -and $GroupDiscoveryScopeToExclude) + { + foreach ($item in $GroupDiscoveryScopeToInclude) + { + if ($GroupDiscoveryScopeToExclude -contains $item.Name) + { + throw ($script:localizedData.GdsInEx -f $item.Name) + } + } + } + + if ((-not $PSBoundParameters.ContainsKey('ScheduleType')) -and ($PSBoundParameters.ContainsKey('Start') -or + $PSBoundParameters.ContainsKey('RecurInterval') -or $PSBoundParameters.ContainsKey('MonthlyWeekOrder') -or + $PSBoundParameters.ContainsKey('DayOfWeek') -or $PSBoundParameters.ContainsKey('DayOfMonth'))) + { + throw $script:localizedData.MissingScheduleType + } + + if ($PSBoundParameters.ContainsKey('TimeSinceLastLogonDays') -and $EnableFilteringExpiredLogon -ne $true) + { + throw $script:localizedData.TimeSinceLastLogon + } + + if ($PSBoundParameters.ContainsKey('TimeSinceLastPasswordUpdateDays') -and $EnableFilteringExpiredPassword -ne $true) + { + throw $script:localizedData.PasswordExpiredFilter + } + + $paramsToCheck = @('Enabled','EnableDeltaDiscovery','DeltaDiscoveryMins','EnableFilteringExpiredLogon', + 'TimeSinceLastLogonDays','EnableFilteringExpiredPassword','TimeSinceLastPasswordUpdateDays', + 'DiscoverDistributionGroupMembership') + + foreach ($param in $PSBoundParameters.GetEnumerator()) + { + if ($paramsToCheck -contains $param.Key) + { + if ($param.Value -ne $state[$param.Key]) + { + Write-Verbose -Message ($script:localizedData.SetCommonSettings -f $param.Key, $param.Value) + $buildingParams += @{ + $param.Key = $param.Value + } + } + } + } + + if ($ScheduleType) + { + $valuesToValidate = @('ScheduleType','RecurInterval','MonthlyWeekOrder','DayOfWeek','DayOfMonth','Start') + foreach ($item in $valuesToValidate) + { + if ($PSBoundParameters.ContainsKey($item)) + { + $scheduleCheck += @{ + $item = $PSBoundParameters[$item] + } + } + } + + $schedResult = Test-CMSchedule @scheduleCheck -State $state + } + + if ($schedResult -eq $false) + { + $sched = Set-CMSchedule @scheduleCheck + $newSchedule = New-CMSchedule @sched + + Write-Verbose -Message $script:localizedData.NewSchedule + $buildingParams += @{ + PollingSchedule = $newSchedule + } + } + + if ($GroupDiscoveryScope -or $GroupDiscoveryScopeToInclude) + { + if ($GroupDiscoveryScope) + { + $refObject = $GroupDiscoveryScope + } + elseif ($GroupDiscoveryScopeToInclude) + { + $refObject = $GroupDiscoveryScopeToInclude + } + + $compareParams = @{ + ReferenceObject = $refObject + DifferenceObject = $state.GroupDiscoveryScope + Property = 'Recurse','Name','LdapLocation' + IncludeEqual = $null + } + + $compare = Compare-Object @compareParams + $removing = @() + $missing = @() + + foreach ($item in $compare) + { + if ($item.SideIndicator -eq '<=') + { + if ($state.GroupDiscoveryScope.Name -contains $item.Name) + { + Write-Verbose -Message ($script:localizedData.GdsUpdate -f $item.Name, $item.LdapLocation, $item.Recurse, $item.LdapLocation, $item.Recurse) + } + else + { + Write-Verbose -Message ($script:localizedData.GdsMissing -f $item.Name, $item.LdapLocation, $item.Recurse) + } + + $cmAddGroup = @{ + SiteCode = $SiteCode + LdapLocation = $item.LdapLocation + Name = $item.Name + RecursiveSearch = $item.Recurse + } + + [array]$groupOus += New-CMADGroupDiscoveryScope @cmAddGroup + } + + if ($GroupDiscoveryScope) + { + if ($item.SideIndicator -eq '=>') + { + Write-Verbose -Message ($script:localizedData.GdsExtra -f $item.Name) + $removing += "$($item.Name)" + } + } + } + } + + if ((-not $GroupDiscoveryScope) -and ($GroupDiscoveryScopeToExclude)) + { + foreach ($item in $GroupDiscoveryScopeToExclude) + { + if ($state.GroupDiscoveryScope.Name -contains $item) + { + Write-Verbose -Message ($script:localizedData.GdsExtra -f $item) + $removing += $item + } + } + } + + if ($removing) + { + Set-CMDiscoveryMethod -ActiveDirectoryGroupDiscovery -SiteCode $SiteCode -RemoveGroupDiscoveryScope $removing + } + + if ($groupOus) + { + $buildingParams += @{ + AddGroupDiscoveryScope = $groupOus + } + } + + if ($buildingParams) + { + Set-CMDiscoveryMethod -ActiveDirectoryGroupDiscovery -SiteCode $SiteCode @buildingParams + } + } + elseif ($state.Enabled -eq $true) + { + Write-Verbose -Message $script:localizedData.SetDisabled + Set-CMDiscoveryMethod -ActiveDirectoryGroupDiscovery -Enabled $false -SiteCode $SiteCode + } + } + catch + { + throw $_ + } + finally + { + Set-Location -Path "$env:temp" + } +} + +<# + .SYNOPSIS + This will set the desired state. + + .PARAMETER SiteCode + Specifies the site code for Configuration Manager site. + + .PARAMETER Enabled + Specifies the enablement of the group discovery method. + + .PARAMETER EnableDeltaDiscovery + Indicates whether Configuration Manager discovers resources created or modified in AD DS + since the last discovery cycle. If you specify a value of $True for this parameter, + specify a value for the DeltaDiscoveryMins parameter. + + .PARAMETER DeltaDiscoveryMins + Specifies the number of minutes for the delta discovery. + + .PARAMETER EnableFilteringExpiredLogon + Indicates whether Configuration Manager discovers only computers that have logged onto a + domain within a specified number of days. Specify the number of days by using the + TimeSinceLastLogonDays parameter. + + .PARAMETER TimeSinceLastLogonDays + Specify the number of days for EnableFilteringExpiredLogon. + + .PARAMETER EnableFilteringExpiredPassword + Indicates whether Configuration Manager discovers only computers that have updated ther + account password within a specified number of days. Specify the number of days by using the + TimeSinceLastPasswordUpdateDays parameter. + + .PARAMETER TimeSinceLastPasswordUpdateDays + Specify the number of days for EnableFilteringExpiredPassword. + + .PARAMETER DiscoverDistributionGroupMembership + Specify if group discovery will discover distribution groups and the members of the group. + + .PARAMETER GroupDiscoveryScope + Specifies an array of Group Discovery Scopes to match to the discovery. + + .PARAMETER GroupDiscoveryScopeToInclude + Specifies an array of Group Discovery Scopes to add to the discovery. + + .PARAMETER GroupDiscoveryScopeToExclude + Specifies an array of names of Group Discovery Scopes to exclude to the discovery. + + .PARAMETER Start + Specifies the start date and start time for the group discovery schedule Month/Day/Year, example 1/1/2020 02:00. + + .PARAMETER ScheduleType + Specifies the schedule type for the group discovery schedule. + + .PARAMETER RecurInterval + Specifies how often the ScheduleType is run. + + .PARAMETER MonthlyByWeek + Specifies week order for MonthlyByWeek schedule type. + + .PARAMETER DayOfWeek + Specifies the day of week name for MonthlyByWeek and Weekly schedules. + + .PARAMETER DayOfMonth + Specifies the day number for MonthlyByDay schedules. + Note specifying 0 sets the schedule to run the last day of the month. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [String] + $SiteCode, + + [Parameter(Mandatory = $true)] + [Boolean] + $Enabled, + + [Parameter()] + [Boolean] + $EnableDeltaDiscovery, + + [Parameter()] + [ValidateRange(5,60)] + [UInt32] + $DeltaDiscoveryMins, + + [Parameter()] + [Boolean] + $EnableFilteringExpiredLogon, + + [Parameter()] + [ValidateRange(14,720)] + [UInt32] + $TimeSinceLastLogonDays, + + [Parameter()] + [Boolean] + $EnableFilteringExpiredPassword, + + [Parameter()] + [ValidateRange(30,720)] + [UInt32] + $TimeSinceLastPasswordUpdateDays, + + [Parameter()] + [Boolean] + $DiscoverDistributionGroupMembership, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $GroupDiscoveryScope, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $GroupDiscoveryScopeToInclude, + + [Parameter()] + [String[]] + $GroupDiscoveryScopeToExclude, + + [Parameter()] + [String] + $Start, + + [Parameter()] + [ValidateSet('MonthlyByDay','MonthlyByWeek','Weekly','Days','Hours','Minutes','None')] + [String] + $ScheduleType, + + [Parameter()] + [UInt32] + $RecurInterval, + + [Parameter()] + [ValidateSet('First','Second','Third','Fourth','Last')] + [String] + $MonthlyWeekOrder, + + [Parameter()] + [ValidateSet('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')] + [String] + $DayOfWeek, + + [Parameter()] + [ValidateRange(0,31)] + [UInt32] + $DayOfMonth + ) + + Import-ConfigMgrPowerShellModule -SiteCode $SiteCode + Set-Location -Path "$($SiteCode):\" + $state = Get-TargetResource -SiteCode $SiteCode -Enabled $Enabled + $result = $true + $testResult = $true + $schedResult = $true + + if ($Enabled -eq $true) + { + if ((-not $PSBoundParameters.ContainsKey('ScheduleType')) -and ($PSBoundParameters.ContainsKey('Start') -or + $PSBoundParameters.ContainsKey('RecurInterval') -or $PSBoundParameters.ContainsKey('MonthlyWeekOrder') -or + $PSBoundParameters.ContainsKey('DayOfWeek') -or $PSBoundParameters.ContainsKey('DayOfMonth'))) + { + Write-Warning -Message $script:localizedData.MissingScheduleType + $badInput = $true + } + + if (($PSBoundParameters.ContainsKey('DeltaDiscoveryMins')) -and ($EnableDeltaDiscovery -eq $false -or + $state.EnableDeltaDiscovery -eq $false)) + { + Write-Warning -Message $script:localizedData.MissingDeltaDiscovery + $badInput = $true + } + + if ($PSBoundParameters.ContainsKey('TimeSinceLastLogonDays') -and $EnableFilteringExpiredLogon -ne $true) + { + Write-Warning -Message $script:localizedData.TimeSinceLastLogon + $badInput = $true + } + + if ($PSBoundParameters.ContainsKey('TimeSinceLastPasswordUpdateDays') -and $EnableFilteringExpiredPassword -ne $true) + { + Write-Warning -Message $script:localizedData.PasswordExpiredFilter + $badInput = $true + } + + $testParams = @{ + CurrentValues = $state + DesiredValues = $PSBoundParameters + ValuesToCheck = @('Enabled','EnableDeltaDiscovery','DeltaDiscoveryMins','EnableFilteringExpiredLogon', + 'TimeSinceLastLogonDays','EnableFilteringExpiredPassword','TimeSinceLastPasswordUpdateDays', + 'DiscoverDistributionGroupMembership') + } + + $testResult = Test-DscParameterState @testParams -TurnOffTypeChecking -Verbose + + if ($ScheduleType) + { + $valuesToValidate = @('ScheduleType','RecurInterval','MonthlyWeekOrder','DayOfWeek','DayOfMonth','Start') + foreach ($item in $valuesToValidate) + { + if ($PSBoundParameters.ContainsKey($item)) + { + $scheduleCheck += @{ + $item = $PSBoundParameters[$item] + } + } + } + + $schedResult = Test-CMSchedule @scheduleCheck -State $state + } + + if (($EnableDeltaDiscovery -eq $true -and $state.EnableDeltaDiscovery -eq $false) -and + (-not $PSBoundParameters.ContainsKey('DeltaDiscoveryMins'))) + { + Write-Warning -Message $script:localizedData.DeltaNoInterval + } + + if ($PSBoundParameters.ContainsKey('GroupDiscoveryScope')) + { + if ($PSBoundParameters.ContainsKey('GroupDiscoveryScopeToInclude') -or + $PSBoundParameters.ContainsKey('GroupDiscoveryScopeToExclude')) + { + Write-Warning -Message $script:localizedData.GdsIgnore + } + } + elseif (-not $PSBoundParameters.ContainsKey('GroupDiscoveryScope') -and + $PSBoundParameters.ContainsKey('GroupDiscoveryScopeToInclude') -and + $PSBoundParameters.ContainsKey('GroupDiscoveryScopeToExclude')) + { + foreach ($item in $GroupDiscoveryScopeToInclude) + { + if ($GroupDiscoveryScopeToExclude -contains $item.Name) + { + Write-Warning -Message ($script:localizedData.GdsInEx -f $item.Name) + $result = $false + } + } + } + + if ($GroupDiscoveryScope -or $GroupDiscoveryScopeToInclude) + { + if ($GroupDiscoveryScope) + { + $refObject = $GroupDiscoveryScope + } + elseif ($GroupDiscoveryScopeToInclude) + { + $refObject = $GroupDiscoveryScopeToInclude + } + + $compareParams = @{ + ReferenceObject = $refObject + DifferenceObject = $state.GroupDiscoveryScope + Property = 'Recurse','Name','LdapLocation' + IncludeEqual = $null + } + + $compare = Compare-Object @compareParams + $removing = @() + $missing = @() + foreach ($item in $compare) + { + if ($item.SideIndicator -eq '<=') + { + if ($state.GroupDiscoveryScope.Name -contains $item.Name) + { + Write-Verbose -Message ($script:localizedData.GdsUpdate -f $item.Name, $item.LdapLocation, $item.Recurse, $item.LdapLocation, $item.Recurse) + } + else + { + Write-Verbose -Message ($script:localizedData.GdsMissing -f $item.Name, $item.LdapLocation, $item.Recurse) + } + + $result = $false + } + + if ($GroupDiscoveryScope) + { + if ($item.SideIndicator -eq '=>') + { + Write-Verbose -Message ($script:localizedData.GdsExtra -f $item.Name) + $result = $false + } + } + } + } + + if ((-not $GroupDiscoveryScope) -and ($GroupDiscoveryScopeToExclude)) + { + foreach ($item in $GroupDiscoveryScopeToExclude) + { + if ($state.GroupDiscoveryScope.Name -contains $item) + { + Write-Verbose -Message ($script:localizedData.GdsExtra -f $item) + $result = $false + } + } + } + + if ($result -eq $false -or $testResult -eq $false -or $schedResult -eq $false -or $badInput -eq $true) + { + $result = $false + } + else + { + $result = $true + } + } + elseif ($state.Enabled -eq $true) + { + Write-Verbose -Message $script:localizedData.TestDisabled + $result = $false + } + + Write-Verbose -Message ($script:localizedData.TestState -f $result) + return $result +} + +Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_CMGroupDiscovery/DSC_CMGroupDiscovery.schema.mof b/source/DSCResources/DSC_CMGroupDiscovery/DSC_CMGroupDiscovery.schema.mof new file mode 100644 index 0000000..d957def --- /dev/null +++ b/source/DSCResources/DSC_CMGroupDiscovery/DSC_CMGroupDiscovery.schema.mof @@ -0,0 +1,30 @@ +[ClassVersion("1.0.0"), FriendlyName("CMGroupDiscovery")] +class DSC_CMGroupDiscovery : OMI_BaseResource +{ + [Key, Description("Specifies the SiteCode for the Configuration Manager site.")] String SiteCode; + [Key, Description("Specifies the enablement of the system discovery method.")] Boolean Enabled; + [Write, Description("Indicates whether Configuration Manager discovers resources created or modified in AD DS since the last discovery cycle.")] Boolean EnableDeltaDiscovery; + [Write, Description("Specifies the number of minutes for the delta discovery.")] UInt32 DeltaDiscoveryMins; + [Write, Description("Indicates whether Configuration Manager discovers only computers that have logged onto a domain within a specified number of days.")] Boolean EnableFilteringExpiredLogon; + [Write, Description("Specify the number of days for EnableFilteringExpiredLogon.")] UInt32 TimeSinceLastLogonDays; + [Write, Description("Indicates whether Configuration Manager discovers only computers that have updated their computer account password within a specified number of days.")] Boolean EnableFilteringExpiredPassword; + [Write, Description("Specify the number of days for EnableFilteringExpiredPassword.")] UInt32 TimeSinceLastPasswordUpdateDays; + [Write, EmbeddedInstance("DSC_CMGroupDiscoveryScope"), Description("Specifies an array of Group Discovery Scopes to match to the discovery.")] String GroupDiscoveryScope[]; + [Write, EmbeddedInstance("DSC_CMGroupDiscoveryScope"), Description("Specifies an array of Group Discovery Scopes to add to the discovery.")] String GroupDiscoveryScopeToInclude[]; + [Write, Description("Specifies an array of names of Group Discovery Scopes to exclude to the discovery.")] String GroupDiscoveryScopeToExclude[]; + [Write, Description("Specify if group discovery will discover distribution groups and the members of the group.")] Boolean DiscoverDistributionGroupMembership; + [Write, Description("Specifies the start date and start time for the group discovery schedule Month/Day/Year, example 1/1/2020 02:00.")] String Start; + [Write, Description("Specifies the schedule type for the group discovery schedule."), ValueMap{"MonthlyByDay","MonthlyByWeek","Weekly","Days","Hours","Minutes","None"}, Values{"MonthlyByDay","MonthlyByWeek","Weekly","Days","Hours","Minutes","None"}] String ScheduleType; + [Write, Description("Specifies how often the ScheduleType is run.")] UInt32 RecurInterval; + [Write, Description("Specifies week order for MonthlyByWeek schedule type."), ValueMap{"First","Second","Third","Fourth","Last"}, Values{"First","Second","Third","Fourth","Last"}] String MonthlyWeekOrder; + [Write, Description("Specifies the day of week name for MonthlyByWeek and Weekly schedules."), ValueMap{"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}, Values{"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}] String DayOfWeek; + [Write, Description("Specifies the day number for MonthlyByDay schedules.")] UInt32 DayOfMonth; +}; + +[ClassVersion("1.0.0")] +class DSC_CMGroupDiscoveryScope +{ + [Required, Description("Specifies the name of the Group Discovery Scope.")] String Name; + [Required, Description("Specifies the LDAP location.")] String LdapLocation; + [Required, Description("Specifies if the LDAP search is recursive.")] Boolean Recurse; +}; diff --git a/source/DSCResources/DSC_CMGroupDiscovery/en-US/DSC_CMGroupDiscovery.strings.psd1 b/source/DSCResources/DSC_CMGroupDiscovery/en-US/DSC_CMGroupDiscovery.strings.psd1 new file mode 100644 index 0000000..8712931 --- /dev/null +++ b/source/DSCResources/DSC_CMGroupDiscovery/en-US/DSC_CMGroupDiscovery.strings.psd1 @@ -0,0 +1,18 @@ +ConvertFrom-StringData @' + RetrieveSettingValue = Getting results for Configuration Manager group discovery method. + TestState = Test-TargetResource compliance check returned: {0}. + TestDisabled = Expected Group Discovery to be set to disabled returned enabled. + SetCommonSettings = Setting {0} to desired setting {1}. + SetDisabled = Setting Group Discovery to disabled. + MissingDeltaDiscovery = When changing delta schedule, delta schedule must be enabled. + GdsIgnore = GroupDiscoveryScope was specified, GroupDiscoveryScopeInclude and GroupDiscoveryScopeToExclude will be ignored. + GdsInEx = GroupDiscoveryScopeToExclude and GroupDiscoveryScopeToInclude contain to same entry {0}, remove from one of the arrays. + GdsMissing = Group Discovery Scope Name: {0} LDAPPath: {1} Recurse {2} is missing. + GdsUpdate = Group Discovery Scope Name: {0} expected LdapLocation: {1} Recurse {2}, returned LdapLocation: {3} Recurse {4}. + GdsExtra = Group Discovery Scope Name {0} is expected to be absent. + DeltaNoInterval = DeltaDiscoveryMins is not specified, specify DeltaDiscoveryMins when enabling Delta Discovery. + NewSchedule = Modifying group discovery schedule. + MissingScheduleType = In order to create a schedule you must specify ScheduleType. + TimeSinceLastLogon = When setting TimeSinceLastLogonDays, EnableFilteringExpiredLogon must be set to true. + PasswordExpiredFilter = When setting TimeSinceLastPasswordUpdateDays, EnableFilteringExpiredPassword must be set to true. +'@ diff --git a/source/Examples/Resources/CMGroupDiscovery/GroupDiscovery_Disabled.ps1 b/source/Examples/Resources/CMGroupDiscovery/GroupDiscovery_Disabled.ps1 new file mode 100644 index 0000000..5cbfe57 --- /dev/null +++ b/source/Examples/Resources/CMGroupDiscovery/GroupDiscovery_Disabled.ps1 @@ -0,0 +1,17 @@ +<# + .SYNOPSIS + A DSC configuration script to set group discovery disabled. +#> +Configuration Example +{ + Import-DscResource -ModuleName ConfigMgrCBDsc + + Node localhost + { + CMGroupDiscovery ExampleSettings + { + SiteCode = 'Lab' + Enabled = $false + } + } +} diff --git a/source/Examples/Resources/CMGroupDiscovery/GroupDiscovery_Enabled.ps1 b/source/Examples/Resources/CMGroupDiscovery/GroupDiscovery_Enabled.ps1 new file mode 100644 index 0000000..c45dd53 --- /dev/null +++ b/source/Examples/Resources/CMGroupDiscovery/GroupDiscovery_Enabled.ps1 @@ -0,0 +1,42 @@ +<# + .SYNOPSIS + A DSC configuration script to set group discovery enabled. +#> +Configuration Example +{ + Import-DscResource -ModuleName ConfigMgrCBDsc + + Node localhost + { + CMGroupDiscovery ExampleSettings + { + SiteCode = 'Lab' + Enabled = $true + ScheduleType = 'MonthlyByWeek' + RecurInterval = 1 + MonthlyWeekOrder = 'Last' + DayOfWeek = 'Friday' + EnableDeltaDiscovery = $true + DeltaDiscoveryMins = 60 + EnableFilteringExpiredLogon = $true + TimeSinceLastLogonDays = 90 + EnableFilteringExpiredPassword = $true + TimeSinceLastPasswordUpdateDays = 90 + DiscoverDistributionGroupMembership = $true + GroupDiscoveryScope = @( + DSC_CMGroupDiscoveryScope + { + Name = 'test1' + LdapLocation = 'LDAP://OU=Test1,DC=contoso,DC=com' + Recurse = $false + } + DSC_CMGroupDiscoveryScope + { + Name = 'test2' + LdapLocation = 'LDAP://OU=Test2,DC=contoso,DC=com' + Recurse = $false + } + ) + } + } +} diff --git a/source/Examples/Resources/CMGroupDiscovery/GroupDiscovery_Include_Exclude.ps1 b/source/Examples/Resources/CMGroupDiscovery/GroupDiscovery_Include_Exclude.ps1 new file mode 100644 index 0000000..949f965 --- /dev/null +++ b/source/Examples/Resources/CMGroupDiscovery/GroupDiscovery_Include_Exclude.ps1 @@ -0,0 +1,41 @@ +<# + .SYNOPSIS + A DSC configuration script for system discovery to include and exclude group discovery scopes. +#> +Configuration Example +{ + Import-DscResource -ModuleName ConfigMgrCBDsc + + Node localhost + { + CMGroupDiscovery ExampleSettings + { + SiteCode = 'Lab' + Enabled = $true + ScheduleType = 'Days' + RecurInterval = 7 + EnableDeltaDiscovery = $true + DeltaDiscoveryMins = 50 + EnableFilteringExpiredLogon = $true + TimeSinceLastLogonDays = 20 + EnableFilteringExpiredPassword = $true + TimeSinceLastPasswordUpdateDays = 40 + DiscoverDistributionGroupMembership = $true + GroupDiscoveryScopeToInclude = @( + DSC_CMGroupDiscoveryScope + { + Name = 'test1' + LdapLocation = 'LDAP://OU=Test1,DC=contoso,DC=com' + Recurse = $false + } + DSC_CMGroupDiscoveryScope + { + Name = 'test2' + LdapLocation = 'LDAP://OU=Test2,DC=contoso,DC=com' + Recurse = $false + } + ) + GroupDiscoveryScopeToExclude = @('Test4') + } + } +} diff --git a/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 b/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 index 2f500db..3a45955 100644 --- a/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 +++ b/source/Modules/ConfigMgrCBDsc.ReverseDsc/ConfigMgrCBDsc.ReverseDsc.psm1 @@ -218,7 +218,7 @@ function Set-OutFile } if ($ResourceName -eq 'CMCollections' -or $ResourceName -eq 'CMAssetIntelligencePoint' -or - $ResourceName -eq 'CMMaintenanceWindows') + $ResourceName -eq 'CMMaintenanceWindows' -or $ResourceName -eq 'CMGroupDiscovery') { if ($cPush.ScheduleType -eq 'None') { @@ -311,6 +311,22 @@ function Set-OutFile $tester += "`t`t)`r`n" } + if (($ResourceName -eq 'CMGroupDiscovery') -and ($cPush.GroupDiscoveryScope)) + { + $col = 'GroupDiscoveryScope' + + $tester += "`t`t$($col.PadRight($updatedCount)) = @(`r`n" + foreach ($item in $cPush.GroupDiscoveryScope) + { + $tester += "`t`t`t@{`r`n" + $tester += "`t`t`t`tName = '$($item.Name)'`r`n" + $tester += "`t`t`t`tLdapLocation = '$($item.LdapLocation)'`r`n" + $tester += "`t`t`t`tRecurse = '$($item.Recurse)'`r`n" + $tester += "`t`t`t}`r`n" + } + $tester += "`t`t)`r`n" + } + if ($MultiEntry -eq $false) { $wPush += "$tester}" @@ -507,6 +523,10 @@ Configuration ConfigureSccm [HashTable] `$CMForestDiscovery, + [Parameter()] + [HashTable] + `$CMGroupDiscovery, + [Parameter()] [HashTable] `$CMHeartbeatDiscovery, @@ -879,6 +899,620 @@ Configuration ConfigureSccm } } + if (`$CMGroupDiscovery) + { + if (`$CMGroupDiscovery.Enabled -eq `$false) + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + } + } + else + { + if (`$CMGroupDiscovery.GroupDiscoveryScope) + { + `$groupScopes = @() + foreach (`$item in `$CMGroupDiscovery.GroupDiscoveryScope) + { + `$groupScopes += DSC_CMGroupDiscoveryScope + { + Name = `$item.Name + LdapLocation = `$item.LdapLocation + Recurse = `$item.Recurse + } + } + } + + if (`$CMGroupDiscovery.DeltaDiscovery -eq `$false) + { + if (`$CMGroupDiscovery.EnableFilteringExpiredLogon -eq `$true -and + `$CMGroupDiscovery.EnableFilteringExpiredPassword -eq `$true) + { + if (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByDay') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfMonth = `$CMGroupDiscovery.DayOfMonth + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByWeek') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + MonthlyWeekOrder = `$CMGroupDiscovery.MonthlyWeekOrder + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'Weekly') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RefreshType = `$CMGroupDiscovery.RefreshType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'None') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + } + } + else + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + } + } + } + elseif (`$CMGroupDiscovery.EnableFilteringExpiredLogon -eq `$true) + { + if (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByDay') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfMonth = `$CMGroupDiscovery.DayOfMonth + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByWeek') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + MonthlyWeekOrder = `$CMGroupDiscovery.MonthlyWeekOrder + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'Weekly') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RefreshType = `$CMGroupDiscovery.RefreshType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'None') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + } + } + else + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + } + } + } + elseif (`$CMGroupDiscovery.EnableFilteringExpiredPassword -eq `$true) + { + if (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByDay') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfMonth = `$CMGroupDiscovery.DayOfMonth + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByWeek') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + MonthlyWeekOrder = `$CMGroupDiscovery.MonthlyWeekOrder + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'Weekly') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RefreshType = `$CMGroupDiscovery.RefreshType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'None') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + } + } + else + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + } + } + } + } + else + { + if (`$CMGroupDiscovery.EnableFilteringExpiredLogon -eq `$true -and + `$CMGroupDiscovery.EnableFilteringExpiredPassword -eq `$true) + { + if (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByDay') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfMonth = `$CMGroupDiscovery.DayOfMonth + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByWeek') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + MonthlyWeekOrder = `$CMGroupDiscovery.MonthlyWeekOrder + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'Weekly') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RefreshType = `$CMGroupDiscovery.RefreshType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'None') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + } + } + else + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + } + } + } + elseif (`$CMGroupDiscovery.EnableFilteringExpiredLogon -eq `$true) + { + if (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByDay') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfMonth = `$CMGroupDiscovery.DayOfMonth + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByWeek') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + MonthlyWeekOrder = `$CMGroupDiscovery.MonthlyWeekOrder + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'Weekly') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RefreshType = `$CMGroupDiscovery.RefreshType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'None') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + } + } + else + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + TimeSinceLastLogonDays = `$CMGroupDiscovery.TimeSinceLastLogonDays + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + } + } + } + elseif (`$CMGroupDiscovery.EnableFilteringExpiredPassword -eq `$true) + { + if (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByDay') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfMonth = `$CMGroupDiscovery.DayOfMonth + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'MonthlyByWeek') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + MonthlyWeekOrder = `$CMGroupDiscovery.MonthlyWeekOrder + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'Weekly') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RefreshType = `$CMGroupDiscovery.RefreshType + RecurInterval = `$CMGroupDiscovery.RecurInterval + DayOfWeek = `$CMGroupDiscovery.DayOfWeek + } + } + elseif (`$CMGroupDiscovery.ScheduleType -eq 'None') + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + } + } + else + { + CMGroupDiscovery GroupDiscoverySettings + { + SiteCode = `$SiteCode + Enabled = `$CMGroupDiscovery.Enabled + EnableDeltaDiscovery = `$CMGroupDiscovery.EnableDeltaDiscovery + DeltaDiscoveryMins = `$CMGroupDiscovery.DeltaDiscoveryMins + EnableFilteringExpiredLogon = `$CMGroupDiscovery.EnableFilteringExpiredLogon + EnableFilteringExpiredPassword = `$CMGroupDiscovery.EnableFilteringExpiredPassword + TimeSinceLastPasswordUpdateDays = `$CMGroupDiscovery.TimeSinceLastPasswordUpdateDays + GroupDiscoveryScope = `$groupScopes + DiscoverDistributionGroupMembership = `$CMGroupDiscovery.DiscoverDistributionGroupMembership + Start = `$CMGroupDiscovery.Start + ScheduleType = `$CMGroupDiscovery.ScheduleType + RecurInterval = `$CMGroupDiscovery.RecurInterval + } + } + } + } + } + } + if (`$CMSiteMaintenance) { foreach (`$task in `$CMSiteMaintenance) @@ -3744,7 +4378,7 @@ function Set-ConfigMgrCBDscReverse 'MaintenanceWindow','ManagementPoint','NetworkDiscovery','PullDistributionPoint', 'PxeDistributionPoint','ReportingServicesPoint','SecurityScopes','ServiceConnection', 'SiteMaintenance','SiteSystemServer','SoftwareDistributionComponent','SoftwareupdatePoint', - 'StatusReportingComponent','SystemDiscovery','UserDiscovery','ConfigFileOnly')] + 'StatusReportingComponent','SystemDiscovery','UserDiscovery','ConfigFileOnly','GroupDiscovery')] [String[]] $Include = 'All', @@ -3756,7 +4390,7 @@ function Set-ConfigMgrCBDscReverse 'MaintenanceWindow','ManagementPoint','NetworkDiscovery','PullDistributionPoint', 'PxeDistributionPoint','ReportingServicesPoint','SecurityScopes','ServiceConnection', 'SiteMaintenance','SiteSystemServer','SoftwareDistributionComponent','SoftwareupdatePoint', - 'StatusReportingComponent','SystemDiscovery','UserDiscovery')] + 'StatusReportingComponent','SystemDiscovery','UserDiscovery','GroupDiscovery')] [String[]] $Exclude, @@ -4240,6 +4874,45 @@ function Set-ConfigMgrCBDscReverse $fileOut += "$wforest`r`n" } + if (($Include -eq 'All' -and $Exclude -notcontains 'GroupDiscovery') -or ($Include -contains 'GroupDiscovery')) + { + $resourceName = 'CMGroupDiscovery' + Write-Verbose -Message ($script:localizedData.SingleOutput -f $resourceName) -Verbose + $groupDisc = ((Get-CMDiscoveryMethod -Name ActiveDirectoryGroupDiscovery -SiteCode $SiteCode).Props | Where-Object -FilterScript {$_.PropertyName -eq 'Settings'}).Value1 + + if ($groupDisc) + { + $wGrpDiscovery = "$resourceName = @{`r`n" + + if ($groupDisc -eq 'INACTIVE') + { + $params = @{ + ResourceName = $resourceName + SiteCode = $SiteCode + ExcludeList = @('SiteCode','EnableDeltaDiscovery','DeltaDiscoveryMins','EnableFilteringExpiredLogon', + 'TimeSinceLastLogonDays','EnableFilteringExpiredPassword','TimeSinceLastPasswordUpdateDays','DiscoverDistributionGroupMembership', + 'GroupDiscoveryScope','Start','ScheduleType','RecurInterval','MonthlyWeekOrder','DayOfWeek','DayOfMonth') + Indent = 1 + Count = 7 + Resources = $resources + } + } + else + { + $params = @{ + ResourceName = $resourceName + SiteCode = $SiteCode + Indent = 1 + Resources = $resources + } + } + + $testThing = Set-OutFile @params + $wGrpDiscovery += "$testThing" + $fileOut += "$wGrpDiscovery`r`n" + } + } + if (($Include -eq 'All' -and $Exclude -notcontains 'HeartbeatDiscovery') -or ($Include -contains 'HeartbeatDiscovery')) { $resourceName = 'CMHeartbeatDiscovery' diff --git a/tests/Unit/CMGroupDiscovery.tests.ps1 b/tests/Unit/CMGroupDiscovery.tests.ps1 new file mode 100644 index 0000000..7eb2327 --- /dev/null +++ b/tests/Unit/CMGroupDiscovery.tests.ps1 @@ -0,0 +1,1029 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param () + +$script:dscModuleName = 'ConfigMgrCBDsc' +$script:dscResourceName = 'DSC_CMGroupDiscovery' + +$script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) + +Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\ConfigMgrCBDscStub.psm1') -Force -WarningAction 'SilentlyContinue' + +# Import DscResource.Test Module +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.' +} + +# Variables used for each Initialize-TestEnvironment +$testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -TestType Unit + +function Invoke-TestCleanup +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} + +# Begin Testing +try +{ + InModuleScope $script:dscResourceName { + + Describe "ConfigMgrCBDsc - DSC_CMGroupDiscovery\Get-TargetResource" -Tag 'Get' { + BeforeAll { + $getInput = @{ + SiteCode = 'Lab' + Enabled = $true + } + + $getCMDiscoveryEnabled = @{ + Props = @( + @{ + PropertyName = 'Enable Incremental Sync' + Value = 1 + } + @{ + PropertyName = 'Startup Schedule' + Value1 = '000120000015A000' + } + @{ + PropertyName = 'Full Sync Schedule' + Value1 = '000120000015A000' + } + @{ + PropertyName = 'Settings' + Value1 = 'Active' + } + @{ + PropertyName = 'Enable Filtering Expired Logon' + Value = 1 + } + @{ + PropertyName = 'Days Since Last Logon' + Value = 20 + } + @{ + PropertyName = 'Enable Filtering Expired Password' + Value = 1 + } + @{ + PropertyName = 'Days Since Last Password Set' + Value = 40 + } + @{ + PropertyName = 'Discover DG Membership' + Value = 1 + } + ) + PropLists = @( + @{ + PropertyListName = 'AD Containers' + Values = @( + 'Test1' + '0' + '0' + 'Test2' + '0' + '1' + ) + } + @{ + PropertyListName = 'Search Bases:Test1' + Values = @('LDAP://OU=Test1,DC=contoso,DC=com') + } + @{ + PropertyListName = 'Search Bases:Test2' + Values = @('LDAP://OU=Test2,DC=contoso,DC=com') + } + ) + } + + $getCMDiscoveryDisabledDelta = @{ + Props = @( + @{ + PropertyName = 'Enable Incremental Sync' + Value = 0 + } + @{ + PropertyName = 'Startup Schedule' + Value1 = '000120000015A000' + } + @{ + PropertyName = 'Full Sync Schedule' + Value1 = '000120000015A000' + } + @{ + PropertyName = 'Settings' + Value1 = 'Active' + } + @{ + PropertyName = 'Enable Filtering Expired Logon' + Value = 1 + } + @{ + PropertyName = 'Days Since Last Logon' + Value = 20 + } + @{ + PropertyName = 'Enable Filtering Expired Password' + Value = 1 + } + @{ + PropertyName = 'Days Since Last Password Set' + Value = 40 + } + @{ + PropertyName = 'Discover DG Membership' + Value = 1 + } + ) + PropLists = @( + @{ + PropertyListName = 'AD Containers' + Values = @( + 'Test1' + '0' + '0' + 'Test2' + '0' + '1' + ) + } + @{ + PropertyListName = 'Search Bases:Test1' + Values = @('LDAP://OU=Test1,DC=contoso,DC=com') + } + @{ + PropertyListName = 'Search Bases:Test2' + Values = @('LDAP://OU=Test2,DC=contoso,DC=com') + } + ) + } + + $getCMDiscoveryDisabled = @{ + Props = @( + @{ + PropertyName = 'Settings' + Value1 = 'InActive' + } + ) + } + + $getMonthlyByWeek = @{ + MinuteDuration = $null + RecurInterval = 1 + WeekOrder = 'First' + HourDuration = $null + Start = '2/1/1970 00:00' + DayOfWeek = 'Friday' + ScheduleType = 'MonthlyByWeek' + MonthDay = $null + DayDuration = $null + } + + $getWeeklyScheduleReturn = @{ + MinuteDuration = $null + RecurInterval = 1 + WeekOrder = $null + HourDuration = $null + Start = '2/1/1970 00:00' + DayOfWeek = 'Friday' + ScheduleType = 'Weekly' + MonthDay = $null + DayDuration = $null + } + + $cmScheduleHours = @{ + DayDuration = 0 + DaySpan = 0 + HourDuration = 0 + HourSpan = 1 + IsGMT = $false + MinuteDuration = 0 + MinuteSpan = 0 + } + + $cmScheduleMins = @{ + DayDuration = 0 + DaySpan = 0 + HourDuration = 0 + HourSpan = 0 + IsGMT = $false + MinuteDuration = 0 + MinuteSpan = 45 + } + + Mock -CommandName Import-ConfigMgrPowerShellModule + Mock -CommandName Set-Location + } + + Context 'When retrieving Group Discovery settings' { + + It 'Should return desired result when delta schedule returns hour' { + Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getCMDiscoveryEnabled } + Mock -CommandName Get-CMSchedule -MockWith { $getMonthlyByWeek } + Mock -CommandName Convert-CMSchedule -MockWith { $cmScheduleHours } + + $result = Get-TargetResource @getInput + $result | Should -BeOfType System.Collections.HashTable + $result.SiteCode | Should -Be -ExpectedValue 'Lab' + $result.Enabled | Should -Be -ExpectedValue $true + $result.EnableDeltaDiscovery | Should -Be -ExpectedValue $true + $result.DeltaDiscoveryMins | Should -Be -ExpectedValue 60 + $result.EnableFilteringExpiredLogon | Should -Be -ExpectedValue $true + $result.TimeSinceLastLogonDays | Should -Be -ExpectedValue 20 + $result.EnableFilteringExpiredPassword | Should -Be -ExpectedValue $true + $result.TimeSinceLastPasswordUpdateDays | Should -Be -ExpectedValue 40 + $result.DiscoverDistributionGroupMembership | Should -Be -ExpectedValue $true + $result.Start | Should -Be -ExpectedValue '2/1/1970 00:00' + $result.ScheduleType | Should -Be -ExpectedValue 'MonthlyByWeek' + $result.RecurInterval | Should -Be -ExpectedValue 1 + $result.DayOfMonth | Should -Be -ExpectedValue $null + $result.DayOfWeek | Should -Be -ExpectedValue 'Friday' + $result.MonthlyWeekOrder | Should -Be -ExpectedValue 'First' + $result.GroupDiscoveryScope | Should -BeOfType '[Microsoft.Management.Infrastructure.CimInstance]' + $result.GroupDiscoveryScope[0].Name | Should -Be -ExpectedValue 'Test1' + $result.GroupDiscoveryScope[0].LdapLocation | Should -Be -ExpectedValue 'LDAP://OU=Test1,DC=contoso,DC=com' + $result.GroupDiscoveryScope[0].Recurse | Should -Be -ExpectedValue $true + $result.GroupDiscoveryScope[1].Name | Should -Be -ExpectedValue 'Test2' + $result.GroupDiscoveryScope[1].LdapLocation | Should -Be -ExpectedValue 'LDAP://OU=Test2,DC=contoso,DC=com' + $result.GroupDiscoveryScope[1].Recurse | Should -Be -ExpectedValue $false + } + + It 'Should return desired result when delta schedule returns minutes' { + Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getCMDiscoveryEnabled } + Mock -CommandName Get-CMSchedule -MockWith { $getMonthlyByWeek } + Mock -CommandName Convert-CMSchedule -MockWith { $cmScheduleMins } + + $result = Get-TargetResource @getInput + $result | Should -BeOfType System.Collections.HashTable + $result.SiteCode | Should -Be -ExpectedValue 'Lab' + $result.Enabled | Should -Be -ExpectedValue $true + $result.EnableDeltaDiscovery | Should -Be -ExpectedValue $true + $result.DeltaDiscoveryMins | Should -Be -ExpectedValue 45 + $result.EnableFilteringExpiredLogon | Should -Be -ExpectedValue $true + $result.TimeSinceLastLogonDays | Should -Be -ExpectedValue 20 + $result.EnableFilteringExpiredPassword | Should -Be -ExpectedValue $true + $result.TimeSinceLastPasswordUpdateDays | Should -Be -ExpectedValue 40 + $result.DiscoverDistributionGroupMembership | Should -Be -ExpectedValue $true + $result.Start | Should -Be -ExpectedValue '2/1/1970 00:00' + $result.ScheduleType | Should -Be -ExpectedValue 'MonthlyByWeek' + $result.RecurInterval | Should -Be -ExpectedValue 1 + $result.DayOfMonth | Should -Be -ExpectedValue $null + $result.DayOfWeek | Should -Be -ExpectedValue 'Friday' + $result.MonthlyWeekOrder | Should -Be -ExpectedValue 'First' + $result.GroupDiscoveryScope | Should -BeOfType '[Microsoft.Management.Infrastructure.CimInstance]' + $result.GroupDiscoveryScope[0].Name | Should -Be -ExpectedValue 'Test1' + $result.GroupDiscoveryScope[0].LdapLocation | Should -Be -ExpectedValue 'LDAP://OU=Test1,DC=contoso,DC=com' + $result.GroupDiscoveryScope[0].Recurse | Should -Be -ExpectedValue $true + $result.GroupDiscoveryScope[1].Name | Should -Be -ExpectedValue 'Test2' + $result.GroupDiscoveryScope[1].LdapLocation | Should -Be -ExpectedValue 'LDAP://OU=Test2,DC=contoso,DC=com' + $result.GroupDiscoveryScope[1].Recurse | Should -Be -ExpectedValue $false + } + + It 'Should return desired result when delta discovery is disabled' { + Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getCMDiscoveryDisabledDelta } + Mock -CommandName Get-CMSchedule -MockWith { $getWeeklyScheduleReturn } + Mock -CommandName Convert-CMSchedule -MockWith { $null } + + $result = Get-TargetResource @getInput + $result | Should -BeOfType System.Collections.HashTable + $result.SiteCode | Should -Be -ExpectedValue 'Lab' + $result.Enabled | Should -Be -ExpectedValue $true + $result.EnableDeltaDiscovery | Should -Be -ExpectedValue $false + $result.DeltaDiscoveryMins | Should -Be -ExpectedValue $null + $result.EnableFilteringExpiredLogon | Should -Be -ExpectedValue $true + $result.TimeSinceLastLogonDays | Should -Be -ExpectedValue 20 + $result.EnableFilteringExpiredPassword | Should -Be -ExpectedValue $true + $result.TimeSinceLastPasswordUpdateDays | Should -Be -ExpectedValue 40 + $result.DiscoverDistributionGroupMembership | Should -Be -ExpectedValue $true + $result.Start | Should -Be -ExpectedValue '2/1/1970 00:00' + $result.ScheduleType | Should -Be -ExpectedValue 'Weekly' + $result.RecurInterval | Should -Be -ExpectedValue 1 + $result.DayOfMonth | Should -Be -ExpectedValue $null + $result.DayOfWeek | Should -Be -ExpectedValue 'Friday' + $result.MonthlyWeekOrder | Should -Be -ExpectedValue $null + $result.GroupDiscoveryScope | Should -BeOfType '[Microsoft.Management.Infrastructure.CimInstance]' + $result.GroupDiscoveryScope[0].Name | Should -Be -ExpectedValue 'Test1' + $result.GroupDiscoveryScope[0].LdapLocation | Should -Be -ExpectedValue 'LDAP://OU=Test1,DC=contoso,DC=com' + $result.GroupDiscoveryScope[0].Recurse | Should -Be -ExpectedValue $true + $result.GroupDiscoveryScope[1].Name | Should -Be -ExpectedValue 'Test2' + $result.GroupDiscoveryScope[1].LdapLocation | Should -Be -ExpectedValue 'LDAP://OU=Test2,DC=contoso,DC=com' + $result.GroupDiscoveryScope[1].Recurse | Should -Be -ExpectedValue $false + } + + It 'Should return desired result when group discovery is disabled' { + Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getCMDiscoveryDisabled } + + $result = Get-TargetResource @getInput + $result | Should -BeOfType System.Collections.HashTable + $result.SiteCode | Should -Be -ExpectedValue 'Lab' + $result.Enabled | Should -Be -ExpectedValue $false + $result.EnableDeltaDiscovery | Should -Be -ExpectedValue $null + $result.DeltaDiscoveryMins | Should -Be -ExpectedValue $null + $result.EnableFilteringExpiredLogon | Should -Be -ExpectedValue $null + $result.TimeSinceLastLogonDays | Should -Be -ExpectedValue $null + $result.EnableFilteringExpiredPassword | Should -Be -ExpectedValue $null + $result.TimeSinceLastPasswordUpdateDays | Should -Be -ExpectedValue $null + $result.DiscoverDistributionGroupMembership | Should -Be -ExpectedValue $null + $result.Start | Should -Be -ExpectedValue $null + $result.ScheduleType | Should -Be -ExpectedValue $null + $result.RecurInterval | Should -Be -ExpectedValue $null + $result.DayOfMonth | Should -Be -ExpectedValue $null + $result.DayOfWeek | Should -Be -ExpectedValue $null + $result.MonthlyWeekOrder | Should -Be -ExpectedValue $null + $result.GroupDiscoveryScope | Should -Be -ExpectedValue $null + } + } + } + + Describe "ConfigMgrCBDsc - DSC_CMGroupDiscovery\Set-TargetResource" -Tag 'Set' { + BeforeAll { + $groupDiscoveryMisMatchInstance = @( + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test3' + 'LdapLocation' = 'LDAP://OU=Test3,DC=Contoso,DC=Com' + 'Recurse' = $false + } ` + -ClientOnly + ), + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test2' + 'LdapLocation' = 'LDAP://OU=Test2,DC=Contoso,DC=Com' + 'Recurse' = $true + } ` + -ClientOnly + ) + ) + + $groupDiscoverySingleInstance = @( + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test2' + 'LdapLocation' = 'LDAP://OU=Test2,DC=Contoso,DC=Com' + 'Recurse' = $false + } ` + -ClientOnly + ) + ) + + $groupdiscoveryInstanceReturn = @( + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test1' + 'LdapLocation' = 'LDAP://OU=Test1,DC=Contoso,DC=Com' + 'Recurse' = $true + } ` + -ClientOnly + ), + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test2' + 'LdapLocation' = 'LDAP://OU=Test2,DC=Contoso,DC=Com' + 'Recurse' = $true + } ` + -ClientOnly + ) + ) + + $getReturnEnabled = @{ + SiteCode = 'Lab' + Enabled = $true + EnableDeltaDiscovery = $true + DeltaDiscoveryMins = 40 + EnableFilteringExpiredLogon = $true + TimeSinceLastLogonDays = 90 + EnableFilteringExpiredPassword = $true + TimeSinceLastPasswordUpdateDays = 90 + DiscoverDistributionGroupMembership = $true + GroupDiscoveryScope = $groupdiscoveryInstanceReturn + Start = '2/1/1970 00:00' + ScheduleType = 'MonthlyByWeek' + DayOfWeek = 'Friday' + MonthlyWeekOrder = 'first' + DayofMonth = $null + RecurInterval = 1 + } + + $getReturnedDisabled = @{ + SiteCode = 'Lab' + Enabled = $false + EnableDeltaDiscovery = $null + DeltaDiscoveryMins = $null + EnableFilteringExpiredLogon = $null + TimeSinceLastLogonDays = $null + EnableFilteringExpiredPassword = $null + TimeSinceLastPasswordUpdateDays = $null + DiscoverDistributionGroupMembership = $null + GroupDiscoveryScope = $null + Start = $null + ScheduleType = $null + DayOfWeek = $null + MonthlyWeekOrder = $null + DayofMonth = $null + RecurInterval = $null + } + + Mock -CommandName Import-ConfigMgrPowerShellModule + Mock -CommandName Set-Location + Mock -CommandName Set-CMDiscoveryMethod + Mock -CommandName New-CMSchedule -MockWith { $true } + Mock -CommandName New-CMADGroupDiscoveryScope -MockWith { $true } + } + + Context 'When Set-TargetResource runs successfully' { + BeforeEach { + $scheduleMisMatch = @{ + SiteCode = 'Lab' + Enabled = $true + EnableDeltaDiscovery = $true + DeltaDiscoveryMins = 60 + EnableFilteringExpiredLogon = $true + TimeSinceLastLogonDays = 50 + EnableFilteringExpiredPassword = $true + TimeSinceLastPasswordUpdateDays = 50 + DiscoverDistributionGroupMembership = $true + GroupDiscoveryScope = $groupdiscoveryInstanceReturn + Start = '2/1/1970 00:00' + ScheduleType = 'MonthlyByDay' + DayofMonth = 10 + RecurInterval = 1 + } + + $groupDiscoveryDisabled = @{ + SiteCode = 'Lab' + Enabled = $false + } + + $scopesMatchParam = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScope = $groupDiscoveryMisMatchInstance + } + + $scopesIncludeParam = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScopeToInclude = $groupDiscoverySingleInstance + } + + $scopesExcludeParam = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScopeToExclude = 'Test2' + } + + $allGroupDiscoveryOptions = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScope = $groupDiscoveryMisMatchInstance + GroupDiscoveryScopeToInclude = $groupDiscoverySingleInstance + GroupDiscoveryScopeToExclude = 'Test2' + } + } + + It 'Should call expected commands for disenabling the group discovery' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Set-TargetResource @scheduleMisMatch + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 0 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 1 -Scope It + } + + It 'Should call expected commands for enabling and changing the schedule' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Set-TargetResource @groupDiscoveryDisabled + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 0 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 1 -Scope It + } + + It 'Should call expected commands for adding and removing group discovery scopes' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Set-TargetResource @scopesMatchParam + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 2 -Scope It + } + + It 'Should call expected commands for include' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Set-TargetResource @scopesIncludeParam + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 1 -Scope It + } + + It 'Should call expected commands for exclude' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Set-TargetResource @scopesExcludeParam + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 0 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 1 -Scope It + } + + It 'Should call expected commands when match and include and exclude are all specified' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Set-TargetResource @allGroupDiscoveryOptions + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 1 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 2 -Scope It + } + } + + Context 'When running Set-TargetResource should throw' { + BeforeEach { + $includeExclude = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScopeToInclude = $groupDiscoverySingleInstance + GroupDiscoveryScopeToExclude = 'Test2' + } + + $includeExcludeMsg = 'GroupDiscoveryScopeToExclude and GroupDiscoveryScopeToInclude contain to same entry Test2, remove from one of the arrays.' + + $getDeltaDisabled = @{ + SiteCode = 'Lab' + Enabled = $true + EnableDeltaDiscovery = $false + DeltaDiscoveryMins = $null + EnableFilteringExpiredLogon = $true + TimeSinceLastLogonDays = 90 + EnableFilteringExpiredPassword = $true + TimeSinceLastPasswordUpdateDays = 90 + DiscoverDistributionGroupMembership = $true + GroupDiscoveryScope = $groupdiscoveryInstanceReturn + Start = '2/1/1970 00:00' + ScheduleType = 'MonthlyByWeek' + DayOfWeek = 'Friday' + MonthlyWeekOrder = 'first' + DayofMonth = $null + RecurInterval = 1 + } + + $deltaDiscovery = @{ + SiteCode = 'Lab' + Enabled = $true + EnableDeltaDiscovery = $true + } + + $deltaDiscoveryMsg = 'DeltaDiscoveryMins is not specified, specify DeltaDiscoveryMins when enabling Delta Discovery.' + + $deltaMinutes = @{ + SiteCode = 'Lab' + Enabled = $true + DeltaDiscoveryMins = 10 + } + + $deltaMinutesMsg = 'When changing delta schedule, delta schedule must be enabled.' + + $missingScheduleType = @{ + SiteCode = 'Lab' + Enabled = $true + Start = '2/1/1970 00:00' + DayOfWeek = 'Friday' + MonthlyWeekOrder = 'first' + } + + $missingScheduleTypeMsg = 'In order to create a schedule you must specify ScheduleType.' + + $timeSinceLastLogon = @{ + SiteCode = 'Lab' + Enabled = $true + TimeSinceLastLogonDays = 15 + } + + $timeSinceLastLogonMsg = 'When setting TimeSinceLastLogonDays, EnableFilteringExpiredLogon must be set to true.' + + $timePasswordUpdate = @{ + SiteCode = 'Lab' + Enabled = $true + TimeSinceLastPasswordUpdateDays = 49 + } + + $passwordExpiredFilterMsg = 'When setting TimeSinceLastPasswordUpdateDays, EnableFilteringExpiredPassword must be set to true.' + } + + It 'Should call expected commands when include and exclude contain the same entry' { + Mock -CommandName Get-TargetResource -MockWith { $getTargetResourceStandardReturn } + + { Set-TargetResource @includeExclude } | Should -Throw -ExpectedMessage $includeExcludeMsg + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 0 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 0 -Scope It + } + + It 'Should call expected commands when enabling delta discovery and not specifying minutes' { + Mock -CommandName Get-TargetResource -MockWith { $getDeltaDisabled } + + { Set-TargetResource @deltaDiscovery } | Should -Throw -ExpectedMessage $deltaDiscoveryMsg + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 0 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 0 -Scope It + } + + It 'Should call expected commands when specifying delta discovery minutes without enabling delta discovery' { + Mock -CommandName Get-TargetResource -MockWith { $getDeltaDisabled } + + { Set-TargetResource @deltaMinutes } | Should -Throw -ExpectedMessage $deltaMinutesMsg + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 0 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 0 -Scope It + } + + It 'Should call expected commands when specifying schedule and not specifying ScheduleType' { + Mock -CommandName Get-TargetResource -MockWith { $getTargetResourceStandardReturn } + + { Set-TargetResource @missingScheduleType } | Should -Throw -ExpectedMessage $missingScheduleTypeMsg + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 0 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 0 -Scope It + } + + It 'Should call expected commands when specifying TimeSinceLastLogonDays and not EnableFilteringExpiredLogon' { + Mock -CommandName Get-TargetResource -MockWith { $getTargetResourceStandardReturn } + + { Set-TargetResource @timeSinceLastLogon } | Should -Throw -ExpectedMessage $timeSinceLastLogonMsg + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 0 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 0 -Scope It + } + + It 'Should call expected commands when specifying TimeSinceLastPasswordUpdateDays and not EnableFilteringExpiredPassword' { + Mock -CommandName Get-TargetResource -MockWith { $getTargetResourceStandardReturn } + + { Set-TargetResource @timePasswordUpdate } | Should -Throw -ExpectedMessage $passwordExpiredFilterMsg + Assert-MockCalled Import-ConfigMgrPowerShellModule -Exactly -Times 1 -Scope It + Assert-MockCalled Set-Location -Exactly -Times 2 -Scope It + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + Assert-MockCalled New-CMSchedule -Exactly -Times 0 -Scope It + Assert-MockCalled New-CMADGroupDiscoveryScope -Exactly -Times 0 -Scope It + Assert-MockCalled Set-CMDiscoveryMethod -Exactly -Times 0 -Scope It + } + } + } + + Describe "ConfigMgrCBDsc - DSC_CMGroupDiscovery\Test-TargetResource" -Tag 'Test' { + BeforeAll { + $groupDiscoveryMisMatchInstance = @( + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test3' + 'LdapLocation' = 'LDAP://OU=Test3,DC=Contoso,DC=Com' + 'Recurse' = $false + } ` + -ClientOnly + ) + ) + + $groupDiscoverySingleInstance = @( + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test2' + 'LdapLocation' = 'LDAP://OU=Test2,DC=Contoso,DC=Com' + 'Recurse' = $true + } ` + -ClientOnly + ) + ) + + $groupdiscoveryInstanceReturn = @( + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test1' + 'LdapLocation' = 'LDAP://OU=Test2,DC=Contoso,DC=Com' + 'Recurse' = $true + } ` + -ClientOnly + ), + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test2' + 'LdapLocation' = 'LDAP://OU=Test2,DC=Contoso,DC=Com' + 'Recurse' = $true + } ` + -ClientOnly + ) + ) + + $getReturnEnabled = @{ + SiteCode = 'Lab' + Enabled = $true + EnableDeltaDiscovery = $true + DeltaDiscoveryMins = 40 + EnableFilteringExpiredLogon = $true + TimeSinceLastLogonDays = 90 + EnableFilteringExpiredPassword = $true + TimeSinceLastPasswordUpdateDays = 90 + DiscoverDistributionGroupMembership = $true + GroupDiscoveryScope = $groupdiscoveryInstanceReturn + Start = '2/1/1970 00:00' + ScheduleType = 'MonthlyByWeek' + DayOfWeek = 'Friday' + MonthlyWeekOrder = 'first' + DayofMonth = $null + RecurInterval = 1 + } + + $getReturnedDisabled = @{ + SiteCode = 'Lab' + Enabled = $false + EnableDeltaDiscovery = $null + DeltaDiscoveryMins = $null + EnableFilteringExpiredLogon = $null + TimeSinceLastLogonDays = $null + EnableFilteringExpiredPassword = $null + TimeSinceLastPasswordUpdateDays = $null + DiscoverDistributionGroupMembership = $null + GroupDiscoveryScope = $null + Start = $null + ScheduleType = $null + DayOfWeek = $null + MonthlyWeekOrder = $null + DayofMonth = $null + RecurInterval = $null + } + + Mock -CommandName Set-Location + Mock -CommandName Import-ConfigMgrPowerShellModule + } + + Context 'When running Test-TargetResource with returned schedule settings' { + BeforeEach { + $groupDiscoverySingleInstanceRecurse = @( + (New-CimInstance -ClassName DSC_CMGroupDiscoveryScope ` + -Namespace root/microsoft/Windows/DesiredStateConfiguration ` + -Property @{ + 'Name' = 'Test2' + 'LdapLocation' = 'LDAP://OU=Test2,DC=Contoso,DC=Com' + 'Recurse' = $false + } ` + -ClientOnly + ) + ) + + $scheduleMisMatch = @{ + SiteCode = 'Lab' + Enabled = $true + EnableDeltaDiscovery = $true + DeltaDiscoveryMins = 60 + EnableFilteringExpiredLogon = $true + TimeSinceLastLogonDays = 50 + EnableFilteringExpiredPassword = $true + TimeSinceLastPasswordUpdateDays = 50 + DiscoverDistributionGroupMembership = $true + GroupDiscoveryScope = $groupdiscoveryInstanceReturn + Start = '2/1/1970 00:00' + ScheduleType = 'MonthlyByDay' + DayofMonth = 10 + RecurInterval = 1 + } + + $groupDiscoveryMismatch = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScope = $groupDiscoveryMisMatchInstance + } + + $groupDiscoveryIncludeMatches = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScopeToInclude = $groupDiscoverySingleInstance + } + + $groupDiscoveryIncludeMismatch = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScopeToInclude = $groupDiscoverySingleInstanceRecurse + } + + $groupDiscoveryMatches = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScopeToExclude = 'Test2' + } + + $groupDiscoveryDisabled = @{ + SiteCode = 'Lab' + Enabled = $false + } + + Mock -CommandName Get-TargetResource -MockWith { $getTargetResourceStandardReturn } + } + + It 'Should return desired result false when group discovery settings mismatch' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @scheduleMisMatch | Should -Be $false + } + + It 'Should return desired result false when GroupDiscoveryScopes match, mismatches' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @groupDiscoveryMismatch | Should -Be $false + } + + It 'Should return desired result true when GroupDiscoveryScopes include, matches' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @groupDiscoveryIncludeMatches | Should -Be $true + } + + It 'Should return desired result true when GroupDiscoveryScopes include, property mismatch' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @groupDiscoveryIncludeMismatch | Should -Be $false + } + + It 'Should return desired result false when GroupDiscoveryScopes exclude, matches' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @groupDiscoveryMatches | Should -Be $false + } + + It 'Should return desired result true when Group Discovery is disabled and expected disabled' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnedDisabled } + + Test-TargetResource @groupDiscoveryDisabled | Should -Be $true + } + + It 'Should return desired result false when Group Discovery is enabled and expected disabled' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @groupDiscoveryDisabled | Should -Be $false + } + } + + Context 'When running Test-TargetResource write warnings' { + BeforeEach { + $includeExclude = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScopeToInclude = $groupDiscoverySingleInstance + GroupDiscoveryScopeToExclude = 'Test2' + } + + $getDeltaDisabled = @{ + SiteCode = 'Lab' + Enabled = $true + EnableDeltaDiscovery = $false + DeltaDiscoveryMins = $null + EnableFilteringExpiredLogon = $true + TimeSinceLastLogonDays = 90 + EnableFilteringExpiredPassword = $true + TimeSinceLastPasswordUpdateDays = 90 + DiscoverDistributionGroupMembership = $true + GroupDiscoveryScope = $groupdiscoveryInstanceReturn + Start = '2/1/1970 00:00' + ScheduleType = 'MonthlyByWeek' + DayOfWeek = 'Friday' + MonthlyWeekOrder = 'first' + DayofMonth = $null + RecurInterval = 1 + } + + $deltaDiscovery = @{ + SiteCode = 'Lab' + Enabled = $true + EnableDeltaDiscovery = $true + } + + $deltaSchedule = @{ + SiteCode = 'Lab' + Enabled = $true + DeltaDiscoveryMins = 5 + } + + $allGroupDiscoveryOptions = @{ + SiteCode = 'Lab' + Enabled = $true + GroupDiscoveryScope = $groupDiscoveryMisMatchInstance + GroupDiscoveryScopeToInclude = $groupDiscoverySingleInstance + GroupDiscoveryScopeToExclude = 'Test2' + } + + $missingScheduleType = @{ + SiteCode = 'Lab' + Enabled = $true + Start = '2/1/1970 00:00' + DayOfWeek = 'Friday' + MonthlyWeekOrder = 'first' + } + + $timeSinceLastLogon = @{ + SiteCode = 'Lab' + Enabled = $true + TimeSinceLastLogonDays = 15 + } + + $timePasswordUpdate = @{ + SiteCode = 'Lab' + Enabled = $true + TimeSinceLastPasswordUpdateDays = 49 + } + } + + It 'Should return desired result false when enabling delta discovery' { + Mock -CommandName Get-TargetResource -MockWith { $getDeltaDisabled } + + Test-TargetResource @deltaDiscovery | Should -Be $false + } + + It 'Should return desired result false when Include and Exclude contain the same name' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @includeExclude | Should -Be $false + } + + It 'Should return desired result false when using all three GroupDiscoveryScope types' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @allGroupDiscoveryOptions | Should -Be $false + } + + It 'Should return desired result false when specifying delta discovery and not enabling delta discovery' { + Mock -CommandName Get-TargetResource -MockWith { $getDeltaDisabled } + + Test-TargetResource @deltaSchedule | Should -Be $false + } + + It 'Should return desired result false when specifying schedule and not specifying ScheduleType' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @missingScheduleType | Should -Be $false + } + + It 'Should return desired result false when specifying TimeSinceLastLogonDays and not EnableFilteringExpiredLogon' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @timeSinceLastLogon | Should -Be $false + } + + It 'Should return desired result false when specifying TimeSinceLastPasswordUpdateDays and not EnableFilteringExpiredPassword' { + Mock -CommandName Get-TargetResource -MockWith { $getReturnEnabled } + + Test-TargetResource @timePasswordUpdate | Should -Be $false + } + } + } + } +} +catch +{ + Invoke-TestCleanup +} diff --git a/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 b/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 index 8b1515d..26a0e5e 100644 --- a/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 +++ b/tests/Unit/ConfigMgrCBDsc.ReverseDsc.tests.ps1 @@ -1069,6 +1069,134 @@ InModuleScope $script:subModuleName { } ) } + @{ + ImplementedAs = 'PowerShell' + Name = 'CMGroupDiscovery' + ModuleName = 'ConfigMgrCBDsc' + Version = '1.0.1' + Properties = @( + @{ + Name = 'SiteCode' + PropertyType = '[string]' + IsMandatory = $true + Values = '{}' + } + @{ + Name = 'Enabled' + PropertyType = '[bool]' + IsMandatory = $true + Values = '{}' + } + @{ + Name = 'DayOfMonth' + PropertyType = '[UInt32]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'DayOfWeek' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'DeltaDiscoveryMins' + PropertyType = '[UInt32]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'DiscoverDistributionGroupMembership' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'EnableDeltaDiscovery' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'EnableFilteringExpiredLogon' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'EnableFilteringExpiredPassword' + PropertyType = '[bool]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'GroupDiscoveryScope' + PropertyType = '[DSC_CMGroupDiscoveryScope[]]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'GroupDiscoveryScopeToExclude' + PropertyType = '[string[]]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'GroupDiscoveryScopeToInclude' + PropertyType = '[DSC_CMGroupDiscoveryScope[]]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'MonthlyWeekOrder' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'RecurInterval' + PropertyType = '[UInt32]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'ScheduleType' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'Start' + PropertyType = '[string]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'TimeSinceLastLogonDays' + PropertyType = '[UInt32]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'TimeSinceLastPasswordUpdateDays' + PropertyType = '[UInt32]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'DependsOn' + PropertyType = '[string[]]' + IsMandatory = $false + Values = '{}' + } + @{ + Name = 'PsDscRunAsCredential' + PropertyType = '[PSCredential]' + IsMandatory = $false + Values = '{}' + } + ) + } @{ ImplementedAs = 'PowerShell' Name = 'CMHeartbeatDiscovery' @@ -2641,6 +2769,96 @@ InModuleScope $script:subModuleName { PSComputerName = 'localhost' } + $getGroupDiscoveryEnabled = @{ + SiteCode = 'Lab' + Props = @( + @{ + PropertyName = 'Settings' + Value1 = 'ACTIVE' + } + ) + } + + $getGroupDiscoveryDisabled = @{ + SiteCode = 'Lab' + Props = @( + @{ + PropertyName = 'Settings' + Value1 = 'INACTIVE' + } + ) + } + + $groupDiscovery = @{ + SiteCode = 'Lab' + Include = 'GroupDiscovery' + } + + $invokeGroupDiscoveryEnabled = @{ + ConfigurationName = $null + DependsOn = $null + ModuleName = 'ConfigMgrCBDsc' + ModuleVersion = 1.0.1 + PsDscRunAsCredential = $null + ResourceId = $null + SourceInfo = $null + DayOfMonth = $null + DayOfWeek = $null + DeltaDiscoveryMins = 50 + DiscoverDistributionGroupMembership = $true + Enabled = $true + EnableDeltaDiscovery = $true + EnableFilteringExpiredLogon = $true + EnableFilteringExpiredPassword = $true + GroupDiscoveryScope = @( + @{ + Name = 'Test1' + LdapLocation = 'OU=Test1,DC=contoso,DC=com' + Recurse = $true + PSComputerName = 'localhost' + } + ) + GroupDiscoveryScopeToExclude = $null + GroupDiscoveryScopeToInclude = $null + MonthlyWeekOrder = $null + RecurInterval = $null + ScheduleType = 'None' + SiteCode = 'Lab' + Start = '2/1/1970 00:00' + TimeSinceLastLogonDays = 20 + TimeSinceLastPasswordUpdateDays = 40 + PSComputerName = 'localhost' + } + + $invokeGroupDiscoveryDisabled = @{ + ConfigurationName = $null + DependsOn = $null + ModuleName = 'ConfigMgrCBDsc' + ModuleVersion = 1.0.1 + PsDscRunAsCredential = $null + ResourceId = $null + SourceInfo = $null + DayOfMonth = $null + DayOfWeek = $null + DeltaDiscoveryMins = $null + DiscoverDistributionGroupMembership = $null + Enabled = $false + EnableDeltaDiscovery = $null + EnableFilteringExpiredLogon = $null + EnableFilteringExpiredPassword = $null + GroupDiscoveryScope = $null + GroupDiscoveryScopeToExclude = $null + GroupDiscoveryScopeToInclude = $null + MonthlyWeekOrder = $null + RecurInterval = $null + ScheduleType = $null + SiteCode = $null + Start = $null + TimeSinceLastLogonDays = $null + TimeSinceLastPasswordUpdateDays = $null + PSComputerName = 'localhost' + } + $getHeartbeatDiscoveryEnabled = @{ SiteCode = 'Lab' Props = @( @@ -2791,31 +3009,31 @@ InModuleScope $script:subModuleName { } $invokeNetworkDiscovery = @{ - ConfigurationName = $null - DependsOn = $null - ModuleName = 'ConfigMgrCBDsc' - ModuleVersion = 1.0.1 - PsDscRunAsCredential = $null - ResourceId = $null - SourceInfo = $null - Enabled = $false - SiteCode = 'Lab' - PSComputerName = 'localhost' + ConfigurationName = $null + DependsOn = $null + ModuleName = 'ConfigMgrCBDsc' + ModuleVersion = 1.0.1 + PsDscRunAsCredential = $null + ResourceId = $null + SourceInfo = $null + Enabled = $false + SiteCode = 'Lab' + PSComputerName = 'localhost' } $getCMDistributionPointInfo = @{ - SiteCode = 'Lab' - ServerName = 'DP03.contoso.com' - IsPullDP = $true - IsPXE = $true + SiteCode = 'Lab' + ServerName = 'DP03.contoso.com' + IsPullDP = $true + IsPXE = $true } $getCMDistributionPointPxePW = @{ - SiteCode = 'Lab' - ServerName = 'DP03.contoso.com' - IsPullDP = $true - IsPXE = $true - PxePassword = 'somepw' + SiteCode = 'Lab' + ServerName = 'DP03.contoso.com' + IsPullDP = $true + IsPXE = $true + PxePassword = 'somepw' } $pullDP = @{ @@ -3503,6 +3721,8 @@ InModuleScope $script:subModuleName { Mock -CommandName Invoke-DscResource -MockWith { $invokeFallbackPoints } -ParameterFilter { $Name -eq 'CMFallbackStatusPoint' } Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getForestDiscoveryEnabled } -ParameterFilter { $Name -eq 'ActiveDirectoryForestDiscovery' } Mock -CommandName Invoke-DscResource -MockWith { $invokeForestDiscoveryEnabled } -ParameterFilter { $Name -eq 'CMForestDiscovery' } + Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getGroupDiscoveryEnabled } -ParameterFilter { $Name -eq 'ActiveDirectoryGroupDiscovery' } + Mock -CommandName Invoke-DscResource -MockWith { $invokeGroupDiscoveryEnabled } -ParameterFilter { $Name -eq 'CMGroupDiscovery' } Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getHeartbeatDiscoveryEnabled } -ParameterFilter { $Name -eq 'HeartbeatDiscovery' } Mock -CommandName Invoke-DscResource -MockWith { $invokeHeartbeatDiscoveryEnabled } -ParameterFilter { $Name -eq 'CMHeartbeatDiscovery' } Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getNetworkDiscoveryEnabled } -ParameterFilter { $Name -eq 'NetworkDiscovery' } @@ -3529,14 +3749,14 @@ 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 26 -Scope It + Assert-MockCalled Invoke-DscResource -Exactly -Times 27 -Scope It Assert-MockCalled Get-CMAdministrativeUser -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMAssetIntelligenceSynchronizationPoint -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMCollection -Exactly -Times 2 -Scope It Assert-MockCalled Get-CMDistributionPointGroup -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMDistributionPoint -Exactly -Times 2 -Scope It Assert-MockCalled Get-CMFallbackStatusPoint -Exactly -Times 1 -Scope It - Assert-MockCalled Get-CMDiscoveryMethod -Exactly -Times 5 -Scope It + Assert-MockCalled Get-CMDiscoveryMethod -Exactly -Times 6 -Scope It Assert-MockCalled Get-CMManagementPoint -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMDistributionPointInfo -Exactly -Times 0 -Scope It Assert-MockCalled Get-CMReportingServicePoint -Exactly -Times 1 -Scope It @@ -3553,22 +3773,23 @@ InModuleScope $script:subModuleName { Assert-MockCalled New-Configuration -Exactly -Times 1 -Scope It } - It 'Should return expected results and call expected commands for Asset Intelligence Point' { + It 'Should return expected results and call expected commands for Forest Discovery Disabled' { Mock -CommandName Get-DscResource -MockWith { $getDscResourceReturn } - Mock -CommandName Invoke-DscResource -MockWith { $invokeCMAssetIntelligencePointNoneSchedule } -ParameterFilter { $Name -eq 'CMAssetIntelligencePoint' } + Mock -CommandName Invoke-DscResource -MockWith { $invokeForestDiscoveryDisabled } + Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getForestDiscoveryDisabled } -ParameterFilter { $Name -eq 'ActiveDirectoryForestDiscovery' } - $result = Set-ConfigMgrCBDscReverse @assetIntell + $result = Set-ConfigMgrCBDscReverse @forestDiscovery $result | Should -BeOfType System.String - $result | Should -Match 'CMAssetIntelligencePoint' + $result | Should -Match 'CMForestDiscovery' Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It Assert-MockCalled Invoke-DscResource -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMAdministrativeUser -Exactly -Times 0 -Scope It - Assert-MockCalled Get-CMAssetIntelligenceSynchronizationPoint -Exactly -Times 1 -Scope It + Assert-MockCalled Get-CMAssetIntelligenceSynchronizationPoint -Exactly -Times 0 -Scope It Assert-MockCalled Get-CMCollection -Exactly -Times 0 -Scope It Assert-MockCalled Get-CMDistributionPointGroup -Exactly -Times 0 -Scope It Assert-MockCalled Get-CMDistributionPoint -Exactly -Times 0 -Scope It Assert-MockCalled Get-CMFallbackStatusPoint -Exactly -Times 0 -Scope It - Assert-MockCalled Get-CMDiscoveryMethod -Exactly -Times 0 -Scope It + Assert-MockCalled Get-CMDiscoveryMethod -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMManagementPoint -Exactly -Times 0 -Scope It Assert-MockCalled Get-CMDistributionPointInfo -Exactly -Times 0 -Scope It Assert-MockCalled Get-CMReportingServicePoint -Exactly -Times 0 -Scope It @@ -3585,14 +3806,14 @@ InModuleScope $script:subModuleName { Assert-MockCalled New-Configuration -Exactly -Times 0 -Scope It } - It 'Should return expected results and call expected commands for Forest Discovery Disabled' { + It 'Should return expected results and call expected commands for Heartbeat Discovery Disabled' { Mock -CommandName Get-DscResource -MockWith { $getDscResourceReturn } - Mock -CommandName Invoke-DscResource -MockWith { $invokeForestDiscoveryDisabled } - Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getForestDiscoveryDisabled } -ParameterFilter { $Name -eq 'ActiveDirectoryForestDiscovery' } + Mock -CommandName Invoke-DscResource -MockWith { $invokeHeartbeatDiscoveryDisabled } -ParameterFilter { $Name -eq 'CMHeartbeatDiscovery' } + Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getHeartbeatDiscoveryDisabled } -ParameterFilter { $Name -eq 'HeartbeatDiscovery' } - $result = Set-ConfigMgrCBDscReverse @forestDiscovery + $result = Set-ConfigMgrCBDscReverse @heartbeatDiscovery $result | Should -BeOfType System.String - $result | Should -Match "CMForestDiscovery" + $result | Should -Match "CMHeartbeatDiscovery" Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It Assert-MockCalled Invoke-DscResource -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMAdministrativeUser -Exactly -Times 0 -Scope It @@ -3618,14 +3839,14 @@ InModuleScope $script:subModuleName { Assert-MockCalled New-Configuration -Exactly -Times 0 -Scope It } - It 'Should return expected results and call expected commands for Heartbeat Discovery Disabled' { + It 'Should return expected results and call expected commands for Group Discovery Disabled' { Mock -CommandName Get-DscResource -MockWith { $getDscResourceReturn } - Mock -CommandName Invoke-DscResource -MockWith { $invokeHeartbeatDiscoveryDisabled } -ParameterFilter { $Name -eq 'CMHeartbeatDiscovery' } - Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getHeartbeatDiscoveryDisabled } -ParameterFilter { $Name -eq 'HeartbeatDiscovery' } + Mock -CommandName Invoke-DscResource -MockWith { $invokeGroupDiscoveryDisabled } -ParameterFilter { $Name -eq 'CMGroupDiscovery' } + Mock -CommandName Get-CMDiscoveryMethod -MockWith { $getGroupDiscoveryDisabled } -ParameterFilter { $Name -eq 'ActiveDirectoryGroupDiscovery' } - $result = Set-ConfigMgrCBDscReverse @heartbeatDiscovery + $result = Set-ConfigMgrCBDscReverse @groupDiscovery $result | Should -BeOfType System.String - $result | Should -Match "CMHeartbeatDiscovery" + $result | Should -Match "CMGroupDiscovery" Assert-MockCalled Get-CMAccount -Exactly -Times 0 -Scope It Assert-MockCalled Invoke-DscResource -Exactly -Times 1 -Scope It Assert-MockCalled Get-CMAdministrativeUser -Exactly -Times 0 -Scope It