Skip to content

Commit

Permalink
Fix Intune device remedation assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
FabienTschanz committed Jun 15, 2024
1 parent 399a7a0 commit c893de8
Show file tree
Hide file tree
Showing 6 changed files with 312 additions and 40 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Change log for Microsoft365DSC

# UNRELEASED

* IntuneDeviceRemediation
* Fix invalid assignment export and import.

# 1.24.612.1

* IntuneAppConfigurationDevicePolicy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,18 +228,22 @@ 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
$assignmentResult += @{
RunRemediationScript = $assignment.RunRemediationScript
RunSchedule = @{
DataType = $assignment.RunSchedule.AdditionalProperties.'@odata.type'
Date = $assignment.RunSchedule.AdditionalProperties.date
Interval = $assignment.RunSchedule.Interval
Time = Get-Date -Format 'HH:mm:ss' -Date $assignment.RunSchedule.AdditionalProperties.time
UseUtc = $assignment.RunSchedule.AdditionalProperties.useUtc
}
Assignment = ConvertFrom-IntunePolicyAssignment -IncludeDeviceFilter:$true -Assignment $assignment
}
$assignmentResult += $assignmentValue
}
$results.Add('Assignments', $assignmentResult)

Expand Down Expand Up @@ -397,14 +401,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
}
Expand Down Expand Up @@ -433,20 +466,49 @@ 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')
{
Write-Verbose -Message "Removing the Intune Device Remediation with Id {$($currentInstance.Id)}"
Write-Verbose -Message "Removing the Intune Device Remediation with Id {$($currentInstance.Id)}"
#region resource generator code
Remove-MgBetaDeviceManagementDeviceHealthScript -DeviceHealthScriptId $currentInstance.Id
#endregion
Expand Down Expand Up @@ -582,29 +644,48 @@ 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*')
{
$source = Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $source

$testResult = Compare-M365DSCComplexObject `
-Source ($source) `
-Target ($target)
if ($key -eq "Assignments")
{
[hashtable[]]$sourcesWithoutAssignment = @()
foreach ($sourceObject in $source)
{
$sourceWithoutAssignment = $sourceObject.Clone()
$sourcesWithoutAssignment += $sourceWithoutAssignment
}

[hashtable[]]$targetsWithoutAssignment = @()
foreach ($targetObject in $target)
{
$targetWithoutAssignment = $targetObject.Clone()
$targetsWithoutAssignment += $targetWithoutAssignment
}

if (-Not $testResult)
$testResult = Compare-M365DSCComplexObject `
-Source ($sourcesWithoutAssignment) `
-Target ($targetsWithoutAssignment)
}
else
{
$testResult = Compare-M365DSCComplexObject `
-Source ($source) `
-Target ($target)
}

if (-not $testResult)
{
$testResult = $false
break
}

$ValuesToCheck.Remove($key) | Out-Null
}
}

$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)"
Expand Down Expand Up @@ -752,7 +833,15 @@ function Export-TargetResource
}
if ($Results.Assignments)
{
$complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.Assignments -CIMInstanceName DeviceManagementConfigurationPolicyAssignments
foreach ($assignment in $Results.Assignments)
{
$runSchedule = Get-M365DSCDRGComplexTypeToString -ComplexObject $assignment.RunSchedule -CIMInstanceName MSFT_IntuneDeviceRemediationRunSchedule
$assignment.RunSchedule = $runSchedule
$target = Get-M365DSCDRGComplexTypeToString -ComplexObject $assignment.Assignment -CIMInstanceName MSFT_DeviceManagementConfigurationPolicyAssignments
$assignment.Assignment = $target | Select-Object -First 1
$assignment = Get-M365DSCDRGComplexTypeToString -ComplexObject $assignment -CIMInstanceName MSFT_IntuneDeviceRemediationPolicyAssignments
}
$complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.Assignments -CIMInstanceName MSFT_IntuneDeviceRemediationPolicyAssignments
if ($complexTypeStringResult)
{
$Results.Assignments = $complexTypeStringResult
Expand All @@ -777,7 +866,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -35,7 +54,7 @@ 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("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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit c893de8

Please sign in to comment.