From 6eacf4f0408bdb458d5b3f5097968a24f87fd3be Mon Sep 17 00:00:00 2001 From: Fabien Tschanz Date: Wed, 11 Sep 2024 23:39:20 +0200 Subject: [PATCH] Fix operating system build range in Intune device compliance policy --- CHANGELOG.md | 4 + ...IntuneDeviceCompliancePolicyWindows10.psm1 | 90 +++++++++++++++---- ...DeviceCompliancePolicyWindows10.schema.mof | 10 ++- 3 files changed, 86 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c43051379a..edc788b229 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,10 @@ * IntuneAntivirusPolicyWindows10SettingCatalog * Fixes an issue with invalid parameter definition. FIXES [#5015](https://github.com/microsoft/Microsoft365DSC/issues/5015) +* IntuneDeviceCompliancePolicyWindows10 + * Fixes an issue where the property `ValidOperatingSystemBuildRanges` was + not exported properly. + FIXES [#5030](https://github.com/microsoft/Microsoft365DSC/issues/5030) * IntuneDeviceConfigurationSharedMultiDevicePolicyWindows10 * Add missing `AccessTokens` parameter to `Export-TargetResource` FIXES [#5034](https://github.com/microsoft/Microsoft365DSC/issues/5034) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 index 81f4c3aa3b..40d34cd35b 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 @@ -139,7 +139,7 @@ function Get-TargetResource $DeviceCompliancePolicyScript, [Parameter()] - [System.Array] + [Microsoft.Management.Infrastructure.CimInstance[]] $ValidOperatingSystemBuildRanges, [Parameter()] @@ -214,6 +214,28 @@ function Get-TargetResource return $nullResult } + $complexValidOperatingSystemBuildRanges = @() + foreach ($currentValidOperatingSystemBuildRanges in $devicePolicy.AdditionalProperties.validOperatingSystemBuildRanges) + { + $myValidOperatingSystemBuildRanges = @{} + if ($null -ne $currentValidOperatingSystemBuildRanges.lowestVersion) + { + $myValidOperatingSystemBuildRanges.Add('LowestVersion', $currentValidOperatingSystemBuildRanges.lowestVersion.ToString()) + } + if ($null -ne $currentValidOperatingSystemBuildRanges.highestVersion) + { + $myValidOperatingSystemBuildRanges.Add('HighestVersion', $currentValidOperatingSystemBuildRanges.highestVersion.ToString()) + } + if ($null -ne $currentValidOperatingSystemBuildRanges.description) + { + $myValidOperatingSystemBuildRanges.Add('Description', $currentValidOperatingSystemBuildRanges.description) + } + if ($myValidOperatingSystemBuildRanges.values.Where({$null -ne $_}).Count -gt 0) + { + $complexValidOperatingSystemBuildRanges += $myValidOperatingSystemBuildRanges + } + } + Write-Verbose -Message "Found Windows 10 Device Compliance Policy with displayName {$DisplayName}" $results = @{ DisplayName = $devicePolicy.DisplayName @@ -249,7 +271,7 @@ function Get-TargetResource ConfigurationManagerComplianceRequired = $devicePolicy.AdditionalProperties.configurationManagerComplianceRequired TpmRequired = $devicePolicy.AdditionalProperties.tpmRequired DeviceCompliancePolicyScript = $devicePolicy.AdditionalProperties.deviceCompliancePolicyScript - ValidOperatingSystemBuildRanges = $devicePolicy.AdditionalProperties.validOperatingSystemBuildRanges + ValidOperatingSystemBuildRanges = $complexValidOperatingSystemBuildRanges Ensure = 'Present' Credential = $Credential ApplicationId = $ApplicationId @@ -262,7 +284,7 @@ function Get-TargetResource $returnAssignments = @() $graphAssignments = Get-MgBetaDeviceManagementDeviceCompliancePolicyAssignment -DeviceCompliancePolicyId $devicePolicy.Id - if ($graphAssignments.count -gt 0) + if ($graphAssignments.Count -gt 0) { $returnAssignments += ConvertFrom-IntunePolicyAssignment ` -IncludeDeviceFilter:$true ` @@ -425,7 +447,7 @@ function Set-TargetResource $DeviceCompliancePolicyScript, [Parameter()] - [System.Array] + [Microsoft.Management.Infrastructure.CimInstance[]] $ValidOperatingSystemBuildRanges, [Parameter()] @@ -701,7 +723,7 @@ function Test-TargetResource $DeviceCompliancePolicyScript, [Parameter()] - [System.Array] + [Microsoft.Management.Infrastructure.CimInstance[]] $ValidOperatingSystemBuildRanges, [Parameter()] @@ -763,25 +785,36 @@ function Test-TargetResource throw "An error occured in Get-TargetResource, the policy {$displayName} will not be processed. Refer to the event viewer logs for more information." } - Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" - Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" - - $ValuesToCheck = $PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() $testResult = $true if ($CurrentValues.Ensure -ne $Ensure) { $testResult = $false } - #region Assignments - if ($testResult) + + #Compare Cim instances + foreach ($key in $PSBoundParameters.Keys) { - $source = Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $PSBoundParameters.Assignments - $target = $CurrentValues.Assignments - $testResult = Compare-M365DSCIntunePolicyAssignment -Source $source -Target $target - $ValuesToCheck.Remove('Assignments') | Out-Null + $source = $PSBoundParameters.$key + $target = $CurrentValues.$key + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') + { + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) + + if (-not $testResult) + { + break + } + + $ValuesToCheck.Remove($key) | Out-Null + } } - #endregion + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" if ($testResult) { @@ -887,7 +920,7 @@ function Export-TargetResource TenantId = $TenantId ApplicationSecret = $ApplicationSecret CertificateThumbprint = $CertificateThumbprint - Managedidentity = $ManagedIdentity.IsPresent + ManagedIdentity = $ManagedIdentity.IsPresent AccessTokens = $AccessTokens } $Results = Get-TargetResource @params @@ -899,6 +932,21 @@ function Export-TargetResource $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` -Results $Results + if ($null -ne $Results.ValidOperatingSystemBuildRanges) + { + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.ValidOperatingSystemBuildRanges ` + -CIMInstanceName 'MicrosoftGraphOperatingSystemVersionRange' ` + -IsArray + if (-not [string]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.ValidOperatingSystemBuildRanges = $complexTypeStringResult + } + else + { + $Results.Remove('ValidOperatingSystemBuildRanges') | Out-Null + } + } if ($Results.Assignments) { $complexTypeStringResult = Get-M365DSCAssignmentsAsString -Params $Results.Assignments @@ -916,6 +964,10 @@ function Export-TargetResource -ModulePath $PSScriptRoot ` -Results $Results ` -Credential $Credential + if ($Results.ValidOperatingSystemBuildRanges) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ValidOperatingSystemBuildRanges' + } if ($Results.Assignments) { $isCIMArray = $false @@ -974,6 +1026,10 @@ function Get-M365DSCIntuneDeviceCompliancePolicyWindows10AdditionalProperties { $propertyName = $property[0].ToString().ToLower() + $property.Substring(1, $property.Length - 1) $propertyValue = $properties.$property + if ($null -ne $propertyValue -and $propertyValue.GetType().Name -like '*cimInstance*') + { + $propertyValue = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $propertyValue + } $results.Add($propertyName, $propertyValue) } } diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.schema.mof index 3dd4d6a55b..ac822b9aa6 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.schema.mof @@ -9,6 +9,14 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments [Write, Description("The collection Id that is the target of the assignment.(ConfigMgr)")] String collectionId; }; +[ClassVersion("1.0.0.0")] +class MSFT_MicrosoftGraphOperatingSystemVersionRange +{ + [Write, Description("The description of this range (e.g. Valid 1702 builds)")] String Description; + [Write, Description("The lowest inclusive version that this range contains.")] String LowestVersion; + [Write, Description("The highest inclusive version that this range contains.")] String HighestVersion; +}; + [ClassVersion("1.0.0.0"), FriendlyName("IntuneDeviceCompliancePolicyWindows10")] class MSFT_IntuneDeviceCompliancePolicyWindows10 : OMI_BaseResource { @@ -46,7 +54,7 @@ class MSFT_IntuneDeviceCompliancePolicyWindows10 : OMI_BaseResource [Write, Description("ConfigurationManagerComplianceRequired of the Windows 10 device compliance policy.")] Boolean ConfigurationManagerComplianceRequired; [Write, Description("TpmRequired of the Windows 10 device compliance policy.")] Boolean TpmRequired; [Write, Description("DeviceCompliancePolicyScript of the Windows 10 device compliance policy.")] String DeviceCompliancePolicyScript; - [Write, Description("ValidOperatingSystemBuildRanges of the Windows 10 device compliance policy.")] String ValidOperatingSystemBuildRanges[]; + [Write, Description("ValidOperatingSystemBuildRanges of the Windows 10 device compliance policy."), EmbeddedInstance("MSFT_MicrosoftGraphOperatingSystemVersionRange")] String ValidOperatingSystemBuildRanges[]; [Write, Description("Present ensures the policy exists, absent ensures it is removed."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; [Write, Description("Credentials of the Intune Admin"), EmbeddedInstance("MSFT_Credential")] string Credential; [Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId;