fix(assignments): use bulk /assign endpoint for removals on all types
Settings Catalog and other bulk-assign types do not support DELETE on individual assignments. Removal now reloads existing assignments, filters out selected targets, sanitizes remaining payloads, and re-POSTs to <API>/<id>/assign. This mirrors the add flow and works universally across all supported object types.
This commit is contained in:
@@ -648,6 +648,29 @@ elseif($action -eq "Remove assignments")
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Helper: compute TargetDesc for an assignment
|
||||
function Get-AssignmentTargetDesc
|
||||
{
|
||||
param($Ass)
|
||||
$tt = $Ass.target."@odata.type"
|
||||
switch($tt)
|
||||
{
|
||||
"#microsoft.graph.groupAssignmentTarget"
|
||||
{
|
||||
$grp = $groups | Where-Object { $_.id -eq $Ass.target.groupId } | Select-Object -First 1
|
||||
return "Include: $(if($grp){$grp.displayName}else{$Ass.target.groupId})"
|
||||
}
|
||||
"#microsoft.graph.exclusionGroupAssignmentTarget"
|
||||
{
|
||||
$grp = $groups | Where-Object { $_.id -eq $Ass.target.groupId } | Select-Object -First 1
|
||||
return "Exclude: $(if($grp){$grp.displayName}else{$Ass.target.groupId})"
|
||||
}
|
||||
"#microsoft.graph.allLicensedUsersAssignmentTarget" { return "All Users" }
|
||||
"#microsoft.graph.allDevicesAssignmentTarget" { return "All Devices" }
|
||||
default { return "Unknown" }
|
||||
}
|
||||
}
|
||||
|
||||
# Execute
|
||||
$success = 0
|
||||
$failed = 0
|
||||
@@ -657,15 +680,42 @@ elseif($action -eq "Remove assignments")
|
||||
if($objAssignments.Count -eq 0) { continue }
|
||||
|
||||
Write-Host "`nProcessing: $($obj."$($objectType.NameProp)")" -ForegroundColor Cyan
|
||||
foreach($ass in $objAssignments)
|
||||
try
|
||||
{
|
||||
try
|
||||
$existing = Invoke-GraphRequest "$($objectType.API)/$($obj.id)/assignments"
|
||||
$remaining = @()
|
||||
foreach($ea in $existing.value)
|
||||
{
|
||||
$desc = Get-AssignmentTargetDesc -Ass $ea
|
||||
if($desc -in $selectedTargetDisplays)
|
||||
{
|
||||
continue
|
||||
}
|
||||
# Sanitize for re-post
|
||||
$clean = $ea | ConvertTo-Json -Depth 50 | ConvertFrom-Json
|
||||
if($clean.PSObject.Properties["id"]) { $clean.PSObject.Properties.Remove("id") }
|
||||
if($clean.PSObject.Properties["source"]) { $clean.PSObject.Properties.Remove("source") }
|
||||
if(-not $clean."@odata.type")
|
||||
{
|
||||
$clean | Add-Member -NotePropertyName "@odata.type" -NotePropertyValue $objectType.AssignmentODataType -Force
|
||||
}
|
||||
$remaining += $clean
|
||||
}
|
||||
|
||||
$assignPayload = @{
|
||||
$objectType.AssignmentsType = $remaining
|
||||
} | ConvertTo-Json -Depth 50 -Compress
|
||||
|
||||
$null = Invoke-GraphRequest "$($objectType.API)/$($obj.id)/assign" -HttpMethod POST -Content $assignPayload
|
||||
foreach($ass in $objAssignments)
|
||||
{
|
||||
$null = Invoke-GraphRequest "$($objectType.API)/$($obj.id)/assignments/$($ass.AssignmentId)" -HttpMethod DELETE
|
||||
Write-Host " OK: Removed $($ass.TargetDesc)" -ForegroundColor Green
|
||||
$success++
|
||||
}
|
||||
catch
|
||||
}
|
||||
catch
|
||||
{
|
||||
foreach($ass in $objAssignments)
|
||||
{
|
||||
Write-Host " ERROR: Failed to remove $($ass.TargetDesc). $($_.Exception.Message)" -ForegroundColor Red
|
||||
$failed++
|
||||
|
||||
Reference in New Issue
Block a user