Files

113 lines
4.1 KiB
Markdown

# Bulk Assignments
## Purpose
`Set-GraphBulkAssignments` adds, replaces, or removes assignment targets across many policies. It is public and UI-independent; the WPF bulk assignment form builds an `IntuneManagerAssignmentSettings` object and calls it.
## Main Files
| File | Responsibility |
| --- | --- |
| `Public/Set-GraphBulkAssignments.ps1` | assignment orchestration and body generation. |
| `Classes/IntuneBaseClasses.ps1` | `IntuneManagerAssignmentSettings` and policy type assignment metadata. |
| `Public/Get-GraphPolicies.ps1` | list policies and include current assignments. |
| `UI/Extensions/IntuneManagerUI.ps1` | bulk assignment UI, group picker, app settings dialog. |
| `UI/XAML/BulkAssignments*.xaml` | forms for assignment targets and settings. |
## Supported Actions
| Action | Behavior |
| --- | --- |
| `Add` | union current assignments with selected assignment rows. |
| `Replace` | replace all current assignments with selected rows. |
| `Remove` | remove selected rows from current assignments. |
Graph `/assign` endpoints replace the full assignment collection, so `Add` and `Remove` must first load current assignments and compute the final collection.
## Target Types
Supported target descriptors:
| Target type | Required fields |
| --- | --- |
| `groupAssignmentTarget` | `GroupId` |
| `exclusionGroupAssignmentTarget` | `GroupId` |
| `allDevicesAssignmentTarget` | none |
| `allLicensedUsersAssignmentTarget` | none |
Group targets can include assignment filters:
| Field | Meaning |
| --- | --- |
| `FilterId` | assignment filter ID. |
| `FilterType` | `include` or `exclude`. |
## Assignment Shapes
Different Graph APIs use different assignment body shapes.
| Shape | Detection | Body |
| --- | --- | --- |
| simple | default | `{ target }` |
| app | `AssignmentsType = mobileAppAssignments` | `{ target, intent, settings? }` |
| script | `AssignmentsType = deviceHealthScriptAssignments` | `{ target, runRemediationScript?, runSchedule? }` |
The function rejects policy types that cannot be represented by one of these shapes.
## Policy Type Gating
`Test-BulkAssignmentSupported` checks:
1. `SupportsAssignments = true`;
2. `AssignmentsType` exists;
3. the type is not a known non-policy assignment API;
4. `Get-BulkAssignmentShape` returns a supported shape.
`Get-BulkAssignmentObjectType` determines assignment entry `@odata.type`. It first checks `PolicyType.AssignmentObjectType`, then uses built-in heuristics for known types.
## No-Op Detection
The command builds tuple signatures for assignment comparison.
| Signature | Used for | Fields |
| --- | --- | --- |
| target signature | Add/Remove identity and dedupe | target type, group ID, filter ID/type, app intent |
| full signature | no-op detection | target signature plus app settings, health-script schedule, remediation flag |
This distinction matters because `Add` should not create duplicates, but `Replace` must still update settings for an existing target.
## App Settings
The UI stores app settings by settings type name, for example `win32LobAppAssignmentSettings`. At execution time:
1. the policy object's `@odata.type` is mapped to the assignment settings type;
2. the selected row's matching settings hashtable is converted to Graph-shaped objects;
3. nested hashtables and arrays are converted recursively for JSON serialization;
4. settings are omitted when not configured so Graph defaults apply.
## Health Script Schedule
Health script settings are stored under the synthetic key `deviceHealthScriptAssignment`. The command turns those values into:
| UI value | Graph type |
| --- | --- |
| `Hourly` | `deviceHealthScriptHourlySchedule` |
| `Daily` | `deviceHealthScriptDailySchedule` |
| `Once` | `deviceHealthScriptRunOnceSchedule` |
## Summary Output
The command returns:
| Field | Meaning |
| --- | --- |
| `Types` | eligible policy types. |
| `PoliciesScanned` | policies loaded. |
| `PoliciesMatched` | policies matching name filter. |
| `PoliciesUpdated` | successful assignment POSTs. |
| `PoliciesSkipped` | no changes required. |
| `PoliciesFailed` | failed POSTs or missing batch responses. |
| `UnsupportedTypes` | selected types skipped by support gate. |
| `Duration` | elapsed time. |