diff --git a/CHANGELOG.md b/CHANGELOG.md index ee2f403f4d..3952493666 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,16 +8,18 @@ * Migrate to new settings catalog cmdlets. * IntuneDeviceManagementComplianceSettings * Initial Release. +* IntuneDeviceRemediation + * Fix invalid assignment export and import. + FIXES [#4726](https://github.com/microsoft/Microsoft365DSC/issues/4726) * M365DSCDRGUtil * Fixes an issue with the settings catalog property generation. -* M365DSCUtil - * Fixes an issue where the comparison with null-valued desired value throws an error. -* DEPENDENCIES - * Updated MSCloudLoginAssistant to version 1.1.18 -* M365DSCDRGUtil * Add `collectionId` export to `ConvertFrom-IntunePolicyAssignment` * Add handling for Intune assignments in `Compare-M365DSCComplexObject` * Fix issue with target handling in `Update-DeviceConfigurationPolicyAssignment` +* M365DSCUtil + * Fixes an issue where the comparison with null-valued desired value throws an error. +* DEPENDENCIES + * Updated MSCloudLoginAssistant to version 1.1.18 * M365DSCResourceGenerator * Update CimInstance comparison template * MISC diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceRemediation/MSFT_IntuneDeviceRemediation.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceRemediation/MSFT_IntuneDeviceRemediation.psm1 index feb6e1bb7b..e377aaaaa9 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceRemediation/MSFT_IntuneDeviceRemediation.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceRemediation/MSFT_IntuneDeviceRemediation.psm1 @@ -228,18 +228,33 @@ function Get-TargetResource AccessTokens = $AccessTokens #endregion } + $assignmentsValues = Get-MgBetaDeviceManagementDeviceHealthScriptAssignment -DeviceHealthScriptId $Id $assignmentResult = @() - foreach ($assignmentEntry in $AssignmentsValues) + foreach ($assignment in $assignmentsValues) { - $assignmentValue = @{ - dataType = $assignmentEntry.Target.AdditionalProperties.'@odata.type' - deviceAndAppManagementAssignmentFilterType = $(if ($null -ne $assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterType) - {$assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterType.ToString()}) - deviceAndAppManagementAssignmentFilterId = $assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterId - groupId = $assignmentEntry.Target.AdditionalProperties.groupId + if (-not [System.String]::IsNullOrEmpty($assignment.RunSchedule.AdditionalProperties.time)) + { + $time = Get-Date -Format 'HH:mm:ss' -Date $assignment.RunSchedule.AdditionalProperties.time + } + else + { + $time = $null + } + + $assignmentResult += @{ + RunRemediationScript = $assignment.RunRemediationScript + RunSchedule = @{ + DataType = $assignment.RunSchedule.AdditionalProperties.'@odata.type' + Date = $assignment.RunSchedule.AdditionalProperties.date + Interval = $assignment.RunSchedule.Interval + Time = $time + UseUtc = $assignment.RunSchedule.AdditionalProperties.useUtc + } + Assignment = (ConvertFrom-IntunePolicyAssignment ` + -IncludeDeviceFilter:$true ` + -Assignments $assignment) | Select-Object -First 1 } - $assignmentResult += $assignmentValue } $results.Add('Assignments', $assignmentResult) @@ -397,14 +412,43 @@ function Set-TargetResource $assignmentsHash = @() foreach ($assignment in $Assignments) { - $assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $Assignment + $assignmentTarget = ConvertTo-IntunePolicyAssignment -Assignments $assignment.Assignment + $runSchedule = $null + if ($null -ne $assignment.RunSchedule.DataType) { + $runSchedule = @{ + '@odata.type' = $assignment.RunSchedule.DataType + } + if (-not [string]::IsNullOrEmpty($assignment.RunSchedule.Date)) + { + $runSchedule.Add('date', $assignment.RunSchedule.Date) + } + if (-not [string]::IsNullOrEmpty($assignment.RunSchedule.Interval)) + { + $runSchedule.Add('interval', $assignment.RunSchedule.Interval) + } + if (-not [string]::IsNullOrEmpty($assignment.RunSchedule.Time)) + { + $runSchedule.Add('time', $assignment.RunSchedule.Time) + } + if (-not [string]::IsNullOrEmpty($assignment.RunSchedule.UseUtc)) + { + $runSchedule.Add('useUtc', $assignment.RunSchedule.UseUtc) + } + } + $assignmentsHash += @{ + runRemediationScript = $assignment.RunRemediationScript + runSchedule = $runSchedule + target = $assignmentTarget.target + } } - if ($policy.id) + if ($policy.Id) { - Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId $policy.id ` - -Targets $assignmentsHash ` - -Repository 'deviceManagement/deviceHealthScripts' + $uri = "/beta/deviceManagement/deviceHealthScripts/$($policy.Id)/assign" + $body = @{ + deviceHealthScriptAssignments = $assignmentsHash + } | ConvertTo-Json -Depth 20 + Invoke-MgGraphRequest -Method POST -Uri $uri -Body $body -ErrorAction Stop 4> $null } #endregion } @@ -433,15 +477,44 @@ function Set-TargetResource Update-MgBetaDeviceManagementDeviceHealthScript ` -DeviceHealthScriptId $currentInstance.Id ` -BodyParameter $UpdateParameters + $assignmentsHash = @() foreach ($assignment in $Assignments) { - $assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $Assignment + $assignmentTarget = ConvertTo-IntunePolicyAssignment -Assignments $assignment.Assignment + $runSchedule = $null + if ($null -ne $assignment.RunSchedule.DataType) { + $runSchedule = @{ + '@odata.type' = $assignment.RunSchedule.DataType + } + if (-not [string]::IsNullOrEmpty($assignment.RunSchedule.Date)) + { + $runSchedule.Add('date', $assignment.RunSchedule.Date) + } + if (-not [string]::IsNullOrEmpty($assignment.RunSchedule.Interval)) + { + $runSchedule.Add('interval', $assignment.RunSchedule.Interval) + } + if (-not [string]::IsNullOrEmpty($assignment.RunSchedule.Time)) + { + $runSchedule.Add('time', $assignment.RunSchedule.Time) + } + if (-not [string]::IsNullOrEmpty($assignment.RunSchedule.UseUtc)) + { + $runSchedule.Add('useUtc', $assignment.RunSchedule.UseUtc) + } + } + $assignmentsHash += @{ + runRemediationScript = $assignment.RunRemediationScript + runSchedule = $runSchedule + target = $assignmentTarget.target + } } - Update-DeviceConfigurationPolicyAssignment ` - -DeviceConfigurationPolicyId $currentInstance.id ` - -Targets $assignmentsHash ` - -Repository 'deviceManagement/deviceHealthScripts' + $uri = "/beta/deviceManagement/deviceHealthScripts/$($currentInstance.Id)/assign" + $body = @{ + deviceHealthScriptAssignments = $assignmentsHash + } | ConvertTo-Json -Depth 20 + Invoke-MgGraphRequest -Method POST -Uri $uri -Body $body -ErrorAction Stop 4> $null #endregion } elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') @@ -582,15 +655,14 @@ function Test-TargetResource { $source = $PSBoundParameters.$key $target = $CurrentValues.$key - if ($source.getType().Name -like '*CimInstance*') + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') { $testResult = Compare-M365DSCComplexObject ` -Source ($source) ` -Target ($target) - if (-Not $testResult) + if (-not $testResult) { - $testResult = $false break } @@ -598,11 +670,8 @@ function Test-TargetResource } } - $ValuesToCheck.remove('Id') | Out-Null - $ValuesToCheck.Remove('Credential') | Out-Null - $ValuesToCheck.Remove('ApplicationId') | Out-Null - $ValuesToCheck.Remove('TenantId') | Out-Null - $ValuesToCheck.Remove('ApplicationSecret') | Out-Null + $ValuesToCheck.Remove('Id') | Out-Null + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" @@ -755,8 +824,24 @@ function Export-TargetResource } if ($Results.Assignments) { - $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.Assignments -CIMInstanceName DeviceManagementConfigurationPolicyAssignments - if ($complexTypeStringResult) + $complexMapping = @( + @{ + Name = 'RunSchedule' + CimInstanceName = 'IntuneDeviceRemediationRunSchedule' + IsRequired = $false + } + @{ + Name = 'Assignment' + CimInstanceName = 'DeviceManagementConfigurationPolicyAssignments' + IsRequired = $true + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.Assignments ` + -CIMInstanceName 'MSFT_IntuneDeviceRemediationPolicyAssignments' ` + -ComplexTypeMapping $complexMapping + + if (-not [string]::IsNullOrEmpty($complexTypeStringResult)) { $Results.Assignments = $complexTypeStringResult } @@ -780,7 +865,10 @@ function Export-TargetResource } if ($Results.Assignments) { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "Assignments" -isCIMArray:$true + $currentDSCBlock = (Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "Assignments" -isCIMArray:$true).Replace("''", "'") + $currentDSCBlock = [Regex]::Replace($currentDSCBlock, "Assignment = '\r\n ", "Assignment = ") + $currentDSCBlock = $currentDSCBlock.Replace("RunSchedule = '", "RunSchedule = ").Replace("}'", "}") + $currentDSCBlock = [Regex]::Replace($currentDSCBlock, "\r\n '", "") } $dscContent += $currentDSCBlock diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceRemediation/MSFT_IntuneDeviceRemediation.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceRemediation/MSFT_IntuneDeviceRemediation.schema.mof index 2951037764..9270cfc537 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceRemediation/MSFT_IntuneDeviceRemediation.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceRemediation/MSFT_IntuneDeviceRemediation.schema.mof @@ -8,7 +8,26 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments [Write, Description("The group Display Name that is the target of the assignment.")] String groupDisplayName; [Write, Description("The collection Id that is the target of the assignment.(ConfigMgr)")] String collectionId; }; -[ClassVersion("1.0.0")] + +[ClassVersion("1.0.0.0")] +class MSFT_IntuneDeviceRemediationRunSchedule +{ + [Write, Description("The type of the schedule."), ValueMap{"#microsoft.graph.deviceHealthScriptRunOnceSchedule","#microsoft.graph.deviceHealthScriptHourlySchedule","#microsoft.graph.deviceHealthScriptDailySchedule"}, Values{"#microsoft.graph.deviceHealthScriptRunOnceSchedule","#microsoft.graph.deviceHealthScriptHourlySchedule","#microsoft.graph.deviceHealthScriptDailySchedule"}] String dataType; + [Write, Description("The date when to run the schedule. Only applicable when the odataType is a run once schedule. Format: 2024-01-01")] String Date; + [Write, Description("The interval of the schedule. Must be 1 in case of a run once schedule.")] UInt32 Interval; + [Write, Description("The time when to run the schedule. Only applicable when the dataType is not an hourly schedule. Format: 01:00:00")] String Time; + [Write, Description("If to use UTC as the time source. Only applicable when the dataType is not an hourly schedule.")] Boolean UseUtc; +}; + +[ClassVersion("1.0.0.0")] +class MSFT_IntuneDeviceRemediationPolicyAssignments +{ + [Write, Description("If the remediation script should be run.")] Boolean RunRemediationScript; + [Write, Description("The run schedule of the remediation."), EmbeddedInstance("MSFT_IntuneDeviceRemediationRunSchedule")] String RunSchedule; + [Write, Description("Represents the assignment of the schedule."), EmbeddedInstance("MSFT_DeviceManagementConfigurationPolicyAssignments")] String Assignment; +}; + +[ClassVersion("1.0.0.0")] class MSFT_MicrosoftGraphDeviceHealthScriptParameter { [Write, Description("Whether Apply DefaultValue When Not Assigned")] Boolean ApplyDefaultValueWhenNotAssigned; @@ -35,8 +54,8 @@ class MSFT_IntuneDeviceRemediation : OMI_BaseResource [Write, Description("Indicate whether PowerShell script(s) should run as 32-bit")] Boolean RunAs32Bit; [Write, Description("Indicates the type of execution context. Possible values are: system, user."), ValueMap{"system","user"}, Values{"system","user"}] String RunAsAccount; [Key, Description("The unique identifier for an entity. Read-only.")] String Id; - [Write, Description("Represents the assignment to the Intune policy."), EmbeddedInstance("MSFT_DeviceManagementConfigurationPolicyAssignments")] String Assignments[]; - [Write, Description("Present ensures the policy exists, absent ensures it is removed.")] string Ensure; + [Write, Description("Represents the assignment to the Intune policy."), EmbeddedInstance("MSFT_IntuneDeviceRemediationPolicyAssignments")] String Assignments[]; + [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 Admin"), EmbeddedInstance("MSFT_Credential")] string Credential; [Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId; [Write, Description("Id of the Azure Active Directory tenant used for authentication.")] String TenantId; diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneDeviceRemediation/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneDeviceRemediation/1-Create.ps1 index 47145d4c9a..0910babcef 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneDeviceRemediation/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneDeviceRemediation/1-Create.ps1 @@ -16,9 +16,20 @@ Configuration Example IntuneDeviceRemediation 'ConfigureDeviceRemediation' { Assignments = @( - MSFT_DeviceManagementConfigurationPolicyAssignments{ - deviceAndAppManagementAssignmentFilterType = 'none' - dataType = '#microsoft.graph.allDevicesAssignmentTarget' + MSFT_IntuneDeviceRemediationPolicyAssignments{ + RunSchedule = MSFT_IntuneDeviceRemediationRunSchedule{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } + RunRemediationScript = $False + Assignment = MSFT_DeviceManagementConfigurationPolicyAssignments{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '11111111-1111-1111-1111-111111111111' + } } ); Credential = $Credscredential diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneDeviceRemediation/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneDeviceRemediation/2-Update.ps1 index dc4bef9bde..116faa673a 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneDeviceRemediation/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneDeviceRemediation/2-Update.ps1 @@ -16,9 +16,20 @@ Configuration Example IntuneDeviceRemediation 'ConfigureDeviceRemediation' { Assignments = @( - MSFT_DeviceManagementConfigurationPolicyAssignments{ - deviceAndAppManagementAssignmentFilterType = 'none' - dataType = '#microsoft.graph.allDevicesAssignmentTarget' + MSFT_IntuneDeviceRemediationPolicyAssignments{ + RunSchedule = MSFT_IntuneDeviceRemediationRunSchedule{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } + RunRemediationScript = $False + Assignment = MSFT_DeviceManagementConfigurationPolicyAssignments{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '11111111-1111-1111-1111-111111111111' + } } ); Credential = $Credscredential diff --git a/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 index 12d8287ca9..4c9c429bfb 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 @@ -1167,7 +1167,7 @@ function ConvertTo-IntunePolicyAssignment } } - return $assignmentResult + return ,$assignmentResult } function Compare-M365DSCIntunePolicyAssignment diff --git a/Modules/Microsoft365DSC/SchemaDefinition.json b/Modules/Microsoft365DSC/SchemaDefinition.json index 7e1fa557a8..55bafee6c4 100644 --- a/Modules/Microsoft365DSC/SchemaDefinition.json +++ b/Modules/Microsoft365DSC/SchemaDefinition.json @@ -29349,6 +29349,56 @@ } ] }, + { + "ClassName": "MSFT_IntuneDeviceRemediationRunSchedule", + "Parameters": [ + { + "CIMType": "String", + "Name": "dataType", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "Date", + "Option": "Write" + }, + { + "CIMType": "UInt32", + "Name": "Interval", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "Time", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "UseUtc", + "Option": "Write" + } + ] + }, + { + "ClassName": "MSFT_IntuneDeviceRemediationPolicyAssignments", + "Parameters": [ + { + "CIMType": "Boolean", + "Name": "RunRemediationScript", + "Option": "Write" + }, + { + "CIMType": "MSFT_IntuneDeviceRemediationRunSchedule", + "Name": "RunSchedule", + "Option": "Write" + }, + { + "CIMType": "MSFT_DeviceManagementConfigurationPolicyAssignments", + "Name": "Assignment", + "Option": "Write" + } + ] + }, { "ClassName": "MSFT_MicrosoftGraphDeviceHealthScriptParameter", "Parameters": [ @@ -29453,7 +29503,7 @@ "Option": "Key" }, { - "CIMType": "MSFT_DeviceManagementConfigurationPolicyAssignments[]", + "CIMType": "MSFT_IntuneDeviceRemediationPolicyAssignments[]", "Name": "Assignments", "Option": "Write" }, diff --git a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.INTUNE.Create.Tests.ps1 b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.INTUNE.Create.Tests.ps1 index 9d6028a771..71cbbb9dc0 100644 --- a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.INTUNE.Create.Tests.ps1 +++ b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.INTUNE.Create.Tests.ps1 @@ -2027,9 +2027,20 @@ IntuneDeviceRemediation 'ConfigureDeviceRemediation' { Assignments = @( - MSFT_DeviceManagementConfigurationPolicyAssignments{ - deviceAndAppManagementAssignmentFilterType = 'none' - dataType = '#microsoft.graph.allDevicesAssignmentTarget' + MSFT_IntuneDeviceRemediationPolicyAssignments{ + RunSchedule = MSFT_IntuneDeviceRemediationRunSchedule{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } + RunRemediationScript = $False + Assignment = MSFT_DeviceManagementConfigurationPolicyAssignments{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '11111111-1111-1111-1111-111111111111' + } } ); Credential = $Credscredential diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneDeviceRemediation.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneDeviceRemediation.Tests.ps1 index 5b991519be..d354e20c66 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneDeviceRemediation.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneDeviceRemediation.Tests.ps1 @@ -56,12 +56,56 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { $Script:ExportMode = $false Mock -CommandName Get-MgBetaDeviceManagementDeviceHealthScriptAssignment -MockWith { + return @( + @{ + Id = "FakeStringValue" + RunRemediationScript = $False + RunSchedule = @{ + Interval = 1 + AdditionalProperties = @{ + '@odata.type' = "#microsoft.graph.deviceHealthScriptRunOnceSchedule" + useUtc = $false + time = "01:00:00.0000000" + date = "2024-01-01" + } + } + Target = @{ + AdditionalProperties = @{ + '@odata.type' = "#microsoft.graph.groupAssignmentTarget" + groupId = "FakeStringValue" + } + "DeviceAndAppManagementAssignmentFilterId" = "FakeStringValue" + "DeviceAndAppManagementAssignmentFilterType" = "none" + } + DeviceHealthScriptId = "FakeStringValue" + RoleScopeTagIds = @("FakeStringValue") + Ensure = "Present" + } + ) } } # Test contexts Context -Name "The IntuneDeviceRemediation should exist but it DOES NOT" -Fixture { BeforeAll { $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_IntuneDeviceRemediationPolicyAssignments -Property @{ + RunSchedule = New-CimInstance -ClassName MSFT_IntuneDeviceRemediationRunSchedule -Property @{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } -ClientOnly + RunRemediationScript = $False + Assignment = New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + deviceAndAppManagementAssignmentFilterId = 'FakeStringValue' + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = 'FakeStringValue' + } -ClientOnly + } -ClientOnly) + ) Description = "FakeStringValue" DetectionScriptContent = "VGVzdA==" # "Test" DetectionScriptParameters = [CimInstance[]]@( @@ -116,6 +160,24 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Context -Name "The IntuneDeviceRemediation exists but it SHOULD NOT" -Fixture { BeforeAll { $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_IntuneDeviceRemediationPolicyAssignments -Property @{ + RunSchedule = New-CimInstance -ClassName MSFT_IntuneDeviceRemediationRunSchedule -Property @{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } -ClientOnly + RunRemediationScript = $False + Assignment = New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + deviceAndAppManagementAssignmentFilterId = 'FakeStringValue' + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = 'FakeStringValue' + } -ClientOnly + } -ClientOnly) + ) Description = "FakeStringValue" DetectionScriptContent = "VGVzdA==" # "Test" DetectionScriptParameters = [CimInstance[]]@( @@ -153,6 +215,24 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Get-MgBetaDeviceManagementDeviceHealthScript -MockWith { return @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_IntuneDeviceRemediationPolicyAssignments -Property @{ + RunSchedule = New-CimInstance -ClassName MSFT_IntuneDeviceRemediationRunSchedule -Property @{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } -ClientOnly + RunRemediationScript = $False + Assignment = New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + deviceAndAppManagementAssignmentFilterId = 'FakeStringValue' + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = 'FakeStringValue' + } -ClientOnly + } -ClientOnly) + ) Description = "FakeStringValue" DetectionScriptContent = [byte[]] @(84, 101, 115, 116) DetectionScriptParameters = @( @@ -205,6 +285,24 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Context -Name "The IntuneDeviceRemediation Exists and Values are already in the desired state" -Fixture { BeforeAll { $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_IntuneDeviceRemediationPolicyAssignments -Property @{ + RunSchedule = New-CimInstance -ClassName MSFT_IntuneDeviceRemediationRunSchedule -Property @{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } -ClientOnly + RunRemediationScript = $False + Assignment = New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + deviceAndAppManagementAssignmentFilterId = 'FakeStringValue' + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = 'FakeStringValue' + } -ClientOnly + } -ClientOnly) + ) Description = "FakeStringValue" DetectionScriptContent = "VGVzdA==" # "Test" DetectionScriptParameters = [CimInstance[]]@( @@ -286,6 +384,24 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Context -Name "The IntuneDeviceRemediation exists and values are NOT in the desired state" -Fixture { BeforeAll { $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_IntuneDeviceRemediationPolicyAssignments -Property @{ + RunSchedule = New-CimInstance -ClassName MSFT_IntuneDeviceRemediationRunSchedule -Property @{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } -ClientOnly + RunRemediationScript = $False + Assignment = New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + deviceAndAppManagementAssignmentFilterId = 'FakeStringValue' + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = 'FakeStringValue' + } -ClientOnly + } -ClientOnly) + ) Description = "FakeStringValue" DetectionScriptContent = "VGVzdA==" # "Test" DetectionScriptParameters = [CimInstance[]]@( @@ -375,6 +491,24 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Get-MgBetaDeviceManagementDeviceHealthScript -MockWith { return @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_IntuneDeviceRemediationPolicyAssignments -Property @{ + RunSchedule = New-CimInstance -ClassName MSFT_IntuneDeviceRemediationRunSchedule -Property @{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } -ClientOnly + RunRemediationScript = $False + Assignment = New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + deviceAndAppManagementAssignmentFilterId = 'FakeStringValue' + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = 'FakeStringValue' + } -ClientOnly + } -ClientOnly) + ) Description = "FakeStringValue" DetectionScriptContent = [byte[]] @(84, 101, 115, 116) DetectionScriptParameters = @( diff --git a/docs/docs/resources/intune/IntuneDeviceRemediation.md b/docs/docs/resources/intune/IntuneDeviceRemediation.md index 72156999e6..d4d43ac6c0 100644 --- a/docs/docs/resources/intune/IntuneDeviceRemediation.md +++ b/docs/docs/resources/intune/IntuneDeviceRemediation.md @@ -17,8 +17,8 @@ | **RunAs32Bit** | Write | Boolean | Indicate whether PowerShell script(s) should run as 32-bit | | | **RunAsAccount** | Write | String | Indicates the type of execution context. Possible values are: system, user. | `system`, `user` | | **Id** | Key | String | The unique identifier for an entity. Read-only. | | -| **Assignments** | Write | MSFT_DeviceManagementConfigurationPolicyAssignments[] | Represents the assignment to the Intune policy. | | -| **Ensure** | Write | String | Present ensures the policy exists, absent ensures it is removed. | | +| **Assignments** | Write | MSFT_IntuneDeviceRemediationPolicyAssignments[] | Represents the assignment to the Intune policy. | | +| **Ensure** | Write | String | Present ensures the policy exists, absent ensures it is removed. | `Present`, `Absent` | | **Credential** | Write | PSCredential | Credentials of the Admin | | | **ApplicationId** | Write | String | Id of the Azure Active Directory application to authenticate with. | | | **TenantId** | Write | String | Id of the Azure Active Directory tenant used for authentication. | | @@ -40,6 +40,28 @@ | **groupDisplayName** | Write | String | The group Display Name that is the target of the assignment. | | | **collectionId** | Write | String | The collection Id that is the target of the assignment.(ConfigMgr) | | +### MSFT_IntuneDeviceRemediationRunSchedule + +#### Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **dataType** | Write | String | The type of the schedule. | `#microsoft.graph.deviceHealthScriptRunOnceSchedule`, `#microsoft.graph.deviceHealthScriptHourlySchedule`, `#microsoft.graph.deviceHealthScriptDailySchedule` | +| **Date** | Write | String | The date when to run the schedule. Only applicable when the odataType is a run once schedule. Format: 2024-01-01 | | +| **Interval** | Write | UInt32 | The interval of the schedule. Must be 1 in case of a run once schedule. | | +| **Time** | Write | String | The time when to run the schedule. Only applicable when the dataType is not an hourly schedule. Format: 01:00:00 | | +| **UseUtc** | Write | Boolean | If to use UTC as the time source. Only applicable when the dataType is not an hourly schedule. | | + +### MSFT_IntuneDeviceRemediationPolicyAssignments + +#### Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **RunRemediationScript** | Write | Boolean | If the remediation script should be run. | | +| **RunSchedule** | Write | MSFT_IntuneDeviceRemediationRunSchedule | The run schedule of the remediation. | | +| **Assignment** | Write | MSFT_DeviceManagementConfigurationPolicyAssignments | Represents the assignment of the schedule. | | + ### MSFT_MicrosoftGraphDeviceHealthScriptParameter #### Parameters @@ -105,9 +127,20 @@ Configuration Example IntuneDeviceRemediation 'ConfigureDeviceRemediation' { Assignments = @( - MSFT_DeviceManagementConfigurationPolicyAssignments{ - deviceAndAppManagementAssignmentFilterType = 'none' - dataType = '#microsoft.graph.allDevicesAssignmentTarget' + MSFT_IntuneDeviceRemediationPolicyAssignments{ + RunSchedule = MSFT_IntuneDeviceRemediationRunSchedule{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } + RunRemediationScript = $False + Assignment = MSFT_DeviceManagementConfigurationPolicyAssignments{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '11111111-1111-1111-1111-111111111111' + } } ); Credential = $Credscredential @@ -148,9 +181,20 @@ Configuration Example IntuneDeviceRemediation 'ConfigureDeviceRemediation' { Assignments = @( - MSFT_DeviceManagementConfigurationPolicyAssignments{ - deviceAndAppManagementAssignmentFilterType = 'none' - dataType = '#microsoft.graph.allDevicesAssignmentTarget' + MSFT_IntuneDeviceRemediationPolicyAssignments{ + RunSchedule = MSFT_IntuneDeviceRemediationRunSchedule{ + Date = '2024-01-01' + Time = '01:00:00' + Interval = 1 + DataType = '#microsoft.graph.deviceHealthScriptRunOnceSchedule' + UseUtc = $False + } + RunRemediationScript = $False + Assignment = MSFT_DeviceManagementConfigurationPolicyAssignments{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '11111111-1111-1111-1111-111111111111' + } } ); Credential = $Credscredential