Skip to content

Commit

Permalink
Merge pull request #5828 from FabienTschanz/fix/device-compliance-policy
Browse files Browse the repository at this point in the history
Fix handling of DeviceCompliancePolicyScript property
  • Loading branch information
NikCharlebois authored Feb 26, 2025
2 parents 0340906 + 5673e39 commit 01eddc9
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 104 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

# UNRELEASED

* IntuneDeviceCompliancePolicyWindows10
* Fixes the handling of the `DeviceCompliancePolicyScript` property.
FIXES [#5510](https://github.com/microsoft/Microsoft365DSC/issues/5510)
* PPTenantSettings
* Corrected issue in the resource schema. The description was a multi-line
string, which is not allowed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function Get-TargetResource
$TpmRequired,

[Parameter()]
[System.String]
[Microsoft.Management.Infrastructure.CimInstance]
$DeviceCompliancePolicyScript,

[Parameter()]
Expand Down Expand Up @@ -206,10 +206,9 @@ function Get-TargetResource

$devicePolicy = Get-MgBetaDeviceManagementDeviceCompliancePolicy `
-All `
-ErrorAction SilentlyContinue | Where-Object `
-FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.windows10CompliancePolicy' -and `
$_.displayName -eq $($DisplayName) }
if (([array]$devicePolicy).count -gt 1)
-Filter "displayName eq '$DisplayName' and isof('microsoft.graph.windows10CompliancePolicy')" `
-ErrorAction SilentlyContinue
if (([array]$devicePolicy).Count -gt 1)
{
throw "A policy with a duplicated displayName {'$DisplayName'} was found - Ensure displayName is unique"
}
Expand Down Expand Up @@ -246,6 +245,19 @@ function Get-TargetResource
}
}

$complexDeviceCompliancePolicyScript = @{}
if ($null -ne $devicePolicy.AdditionalProperties.deviceCompliancePolicyScript)
{
Write-Verbose -Message "Resolving Device Compliance Policy Script with Id {$($devicePolicy.AdditionalProperties.deviceCompliancePolicyScript.deviceComplianceScriptId)}"
$policyScript = Invoke-MgGraphRequest -Uri "/beta/deviceManagement/deviceComplianceScripts/$($devicePolicy.AdditionalProperties.deviceCompliancePolicyScript.deviceComplianceScriptId)" -Method GET
$complexDeviceCompliancePolicyScript.Add('DisplayName', $policyScript.displayName)
$complexDeviceCompliancePolicyScript.Add('RulesContent', [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($devicePolicy.AdditionalProperties.deviceCompliancePolicyScript.rulesContent)))
}
if ($complexDeviceCompliancePolicyScript.Keys.Count -eq 0)
{
$complexDeviceCompliancePolicyScript = $null
}

Write-Verbose -Message "Found Windows 10 Device Compliance Policy with displayName {$DisplayName}"
$results = @{
DisplayName = $devicePolicy.DisplayName
Expand Down Expand Up @@ -280,7 +292,7 @@ function Get-TargetResource
DeviceThreatProtectionRequiredSecurityLevel = $devicePolicy.AdditionalProperties.deviceThreatProtectionRequiredSecurityLevel
ConfigurationManagerComplianceRequired = $devicePolicy.AdditionalProperties.configurationManagerComplianceRequired
TpmRequired = $devicePolicy.AdditionalProperties.tpmRequired
DeviceCompliancePolicyScript = $devicePolicy.AdditionalProperties.deviceCompliancePolicyScript
DeviceCompliancePolicyScript = $complexDeviceCompliancePolicyScript
ValidOperatingSystemBuildRanges = $complexValidOperatingSystemBuildRanges
Ensure = 'Present'
Credential = $Credential
Expand Down Expand Up @@ -453,7 +465,7 @@ function Set-TargetResource
$TpmRequired,

[Parameter()]
[System.String]
[Microsoft.Management.Infrastructure.CimInstance]
$DeviceCompliancePolicyScript,

[Parameter()]
Expand Down Expand Up @@ -515,13 +527,7 @@ function Set-TargetResource
#endregion

$currentDeviceWindows10Policy = Get-TargetResource @PSBoundParameters

$PSBoundParameters.Remove('Ensure') | Out-Null
$PSBoundParameters.Remove('Credential') | Out-Null
$PSBoundParameters.Remove('ApplicationId') | Out-Null
$PSBoundParameters.Remove('TenantId') | Out-Null
$PSBoundParameters.Remove('ApplicationSecret') | Out-Null
$PSBoundParameters.Remove('AccessTokens') | Out-Null
$BoundParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters

$scheduledActionsForRule = @{
'@odata.type' = '#microsoft.graph.deviceComplianceScheduledActionForRule'
Expand All @@ -534,14 +540,34 @@ function Set-TargetResource
)
}

if ($null -ne $BoundParameters.DeviceCompliancePolicyScript)
{
$script = $BoundParameters.DeviceCompliancePolicyScript
$scriptName = $script.Displayname
$scriptRulesContent = $script.RulesContent

$complianceScript = (Invoke-MgGraphRequest -Uri "/beta/deviceManagement/deviceComplianceScripts?`$filter=displayName eq '$scriptName'" -Method GET).value
if ($complianceScript.Count -eq 0)
{
throw "The referenced Intune Device Compliance Script with DisplayName {$scriptName} was not found"
}

$script = @{
deviceComplianceScriptId = $complianceScript.id
rulesContent = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($scriptRulesContent))
}
$BoundParameters.Remove('DeviceCompliancePolicyScript') | Out-Null
$BoundParameters.Add('DeviceCompliancePolicyScript', $script)
}

if ($Ensure -eq 'Present' -and $currentDeviceWindows10Policy.Ensure -eq 'Absent')
{
Write-Verbose -Message "Creating new Intune Device Compliance Windows 10 Policy {$DisplayName}"
$PSBoundParameters.Remove('DisplayName') | Out-Null
$PSBoundParameters.Remove('Description') | Out-Null
$PSBoundParameters.Remove('Assignments') | Out-Null
$BoundParameters.Remove('DisplayName') | Out-Null
$BoundParameters.Remove('Description') | Out-Null
$BoundParameters.Remove('Assignments') | Out-Null

$AdditionalProperties = Get-M365DSCIntuneDeviceCompliancePolicyWindows10AdditionalProperties -Properties ([System.Collections.Hashtable]$PSBoundParameters)
$AdditionalProperties = Get-M365DSCIntuneDeviceCompliancePolicyWindows10AdditionalProperties -Properties ([System.Collections.Hashtable]$BoundParameters)
$policy = New-MgBetaDeviceManagementDeviceCompliancePolicy -DisplayName $DisplayName `
-Description $Description `
-AdditionalProperties $AdditionalProperties `
Expand All @@ -563,11 +589,11 @@ function Set-TargetResource
-FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.windows10CompliancePolicy' -and `
$_.displayName -eq $($DisplayName) }

$PSBoundParameters.Remove('DisplayName') | Out-Null
$PSBoundParameters.Remove('Description') | Out-Null
$PSBoundParameters.Remove('Assignments') | Out-Null
$BoundParameters.Remove('DisplayName') | Out-Null
$BoundParameters.Remove('Description') | Out-Null
$BoundParameters.Remove('Assignments') | Out-Null

$AdditionalProperties = Get-M365DSCIntuneDeviceCompliancePolicyWindows10AdditionalProperties -Properties ([System.Collections.Hashtable]$PSBoundParameters)
$AdditionalProperties = Get-M365DSCIntuneDeviceCompliancePolicyWindows10AdditionalProperties -Properties ([System.Collections.Hashtable]$BoundParameters)
Update-MgBetaDeviceManagementDeviceCompliancePolicy -AdditionalProperties $AdditionalProperties `
-Description $Description `
-DeviceCompliancePolicyId $configDevicePolicy.Id
Expand Down Expand Up @@ -729,7 +755,7 @@ function Test-TargetResource
$TpmRequired,

[Parameter()]
[System.String]
[Microsoft.Management.Infrastructure.CimInstance]
$DeviceCompliancePolicyScript,

[Parameter()]
Expand Down Expand Up @@ -795,7 +821,7 @@ 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."
}

$ValuesToCheck = ([Hashtable]$PSBoundParameters).clone()
$ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone()
$testResult = $true

#Compare Cim instances
Expand Down Expand Up @@ -952,6 +978,20 @@ function Export-TargetResource
$Results.Remove('ValidOperatingSystemBuildRanges') | Out-Null
}
}
if ($null -ne $Results.DeviceCompliancePolicyScript)
{
$complexTypeStringResult = Get-M365DSCDRGComplexTypeToString `
-ComplexObject $Results.DeviceCompliancePolicyScript `
-CIMInstanceName 'MicrosoftGraphDeviceCompliancePolicyScript'
if (-not [string]::IsNullOrWhiteSpace($complexTypeStringResult))
{
$Results.DeviceCompliancePolicyScript = $complexTypeStringResult
}
else
{
$Results.Remove('DeviceCompliancePolicyScript') | Out-Null
}
}
if ($null -ne $Results.Assignments)
{
$complexMapping = @(
Expand Down Expand Up @@ -980,7 +1020,7 @@ function Export-TargetResource
-ModulePath $PSScriptRoot `
-Results $Results `
-Credential $Credential `
-NoEscape @('ValidOperatingSystemBuildRanges', 'Assignments')
-NoEscape @('ValidOperatingSystemBuildRanges', 'DeviceCompliancePolicyScript', 'Assignments')

$dscContent += $currentDSCBlock

Expand Down Expand Up @@ -1041,82 +1081,4 @@ function Get-M365DSCIntuneDeviceCompliancePolicyWindows10AdditionalProperties
return $results
}

function Get-M365DSCAssignmentsAsString
{
[CmdletBinding()]
[OutputType([System.String])]
param(
[Parameter()]
[System.Object[]]
$Params
)

if ($null -eq $params)
{
return $null
}
$currentProperty = "@(`r`n"
$space = ' '
$nbParam = 0
$hasValue = $false
foreach ($rule in $params)
{

$currentProperty += "$($space)MSFT_DeviceManagementConfigurationPolicyAssignments{`r`n"
foreach ($key in $rule.Keys)
{
$value = $rule[$key]
if (-not [System.String]::IsNullOrEmpty($value))
{
$currentProperty += ' ' + $key + " = '" + $value + "'`r`n"
$hasValue = $true
}

}
$currentProperty += ' }'
if ($nbParam -lt ($params.Count - 1) )
{
$nbParam++
$currentProperty += "`r`n"
}

}
$currentProperty += ')'
if (-not $hasValue)
{
return '@()'
}
return $currentProperty
}

function Get-M365DSCAssignmentsAsHashtable
{
[CmdletBinding()]
param(
[Parameter()]
[Microsoft.Management.Infrastructure.CimInstance]
$CIMAssignment
)

if ($null -eq $CIMAssignment)
{
return $null
}
$CIMAssignmentAsHash = @{}
$keys = $CIMAssignment | Get-Member -MemberType Properties

foreach ($key in $keys)
{
if ($CIMAssignment.$($key.Name))
{
$CIMAssignmentAsHash.Add($key.Name, $CIMAssignment.$($key.Name))
}
}
if ($CIMAssignmentAsHash.Count -eq 0)
{
return $null
}
return $CIMAssignmentAsHash
}

Export-ModuleMember -Function *-TargetResource
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ class MSFT_MicrosoftGraphOperatingSystemVersionRange
[Write, Description("The highest inclusive version that this range contains.")] String HighestVersion;
};

[ClassVersion("1.0.0.0")]
class MSFT_MicrosoftGraphDeviceCompliancePolicyScript
{
[Key, Description("Device compliance script name.")] String DisplayName;
[Write, Description("Rules content of the custom settings.")] String RulesContent;
};

[ClassVersion("1.0.0.0"), FriendlyName("IntuneDeviceCompliancePolicyWindows10")]
class MSFT_IntuneDeviceCompliancePolicyWindows10 : OMI_BaseResource
{
Expand Down Expand Up @@ -53,7 +60,7 @@ class MSFT_IntuneDeviceCompliancePolicyWindows10 : OMI_BaseResource
[Write, Description("DeviceThreatProtectionRequiredSecurityLevel of the Windows 10 device compliance policy."), ValueMap{"Unavailable","Secured","Low", "Medium","High","NotSet"}, Values{"Unavailable","Secured","Low", "Medium","High","NotSet"}] String DeviceThreatProtectionRequiredSecurityLevel;
[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("DeviceCompliancePolicyScript of the Windows 10 device compliance policy."), EmbeddedInstance("MSFT_MicrosoftGraphDeviceCompliancePolicyScript")] String DeviceCompliancePolicyScript;
[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;
Expand Down

0 comments on commit 01eddc9

Please sign in to comment.