|
15 | 15 | $TenantFilter = $Request.Query.tenantFilter |
16 | 16 |
|
17 | 17 | try { |
18 | | - # Use bulk requests to get both managed app policies and mobile app configurations |
| 18 | + # Use bulk requests to get groups, managed app policies and mobile app configurations |
19 | 19 | $BulkRequests = @( |
| 20 | + @{ |
| 21 | + id = 'Groups' |
| 22 | + method = 'GET' |
| 23 | + url = '/groups?$top=999&$select=id,displayName' |
| 24 | + } |
20 | 25 | @{ |
21 | 26 | id = 'ManagedAppPolicies' |
22 | 27 | method = 'GET' |
23 | | - url = '/deviceAppManagement/managedAppPolicies?$orderby=displayName' |
| 28 | + url = '/deviceAppManagement/managedAppPolicies?$expand=assignments&$orderby=displayName' |
24 | 29 | } |
25 | 30 | @{ |
26 | 31 | id = 'MobileAppConfigurations' |
27 | 32 | method = 'GET' |
28 | | - url = '/deviceAppManagement/mobileAppConfigurations?$orderby=displayName' |
| 33 | + url = '/deviceAppManagement/mobileAppConfigurations?$expand=assignments&$orderby=displayName' |
29 | 34 | } |
30 | 35 | ) |
31 | 36 |
|
32 | 37 | $BulkResults = New-GraphBulkRequest -Requests $BulkRequests -tenantid $TenantFilter |
33 | 38 |
|
| 39 | + # Extract groups for resolving assignment names |
| 40 | + $Groups = ($BulkResults | Where-Object { $_.id -eq 'Groups' }).body.value |
| 41 | + |
34 | 42 | $GraphRequest = [System.Collections.Generic.List[object]]::new() |
35 | 43 |
|
36 | | - # Process Managed App Policies |
| 44 | + # Process Managed App Policies - these need separate assignment lookups |
37 | 45 | $ManagedAppPolicies = ($BulkResults | Where-Object { $_.id -eq 'ManagedAppPolicies' }).body.value |
38 | 46 | if ($ManagedAppPolicies) { |
| 47 | + # Build bulk requests for assignments of policies that support them |
| 48 | + $AssignmentRequests = [System.Collections.Generic.List[object]]::new() |
| 49 | + foreach ($Policy in $ManagedAppPolicies) { |
| 50 | + # Only certain policy types support assignments endpoint |
| 51 | + $odataType = $Policy.'@odata.type' |
| 52 | + if ($odataType -match 'androidManagedAppProtection|iosManagedAppProtection|windowsManagedAppProtection|targetedManagedAppConfiguration') { |
| 53 | + $urlSegment = switch -Wildcard ($odataType) { |
| 54 | + '*androidManagedAppProtection*' { 'androidManagedAppProtections' } |
| 55 | + '*iosManagedAppProtection*' { 'iosManagedAppProtections' } |
| 56 | + '*windowsManagedAppProtection*' { 'windowsManagedAppProtections' } |
| 57 | + '*targetedManagedAppConfiguration*' { 'targetedManagedAppConfigurations' } |
| 58 | + } |
| 59 | + if ($urlSegment) { |
| 60 | + $AssignmentRequests.Add(@{ |
| 61 | + id = $Policy.id |
| 62 | + method = 'GET' |
| 63 | + url = "/deviceAppManagement/$urlSegment('$($Policy.id)')/assignments" |
| 64 | + }) |
| 65 | + } |
| 66 | + } |
| 67 | + } |
| 68 | + |
| 69 | + # Fetch assignments in bulk if we have any |
| 70 | + $AssignmentResults = @{} |
| 71 | + if ($AssignmentRequests.Count -gt 0) { |
| 72 | + $AssignmentBulkResults = New-GraphBulkRequest -Requests $AssignmentRequests -tenantid $TenantFilter |
| 73 | + foreach ($result in $AssignmentBulkResults) { |
| 74 | + if ($result.body.value) { |
| 75 | + $AssignmentResults[$result.id] = $result.body.value |
| 76 | + } |
| 77 | + } |
| 78 | + } |
| 79 | + |
39 | 80 | foreach ($Policy in $ManagedAppPolicies) { |
40 | 81 | $policyType = switch -Wildcard ($Policy.'@odata.type') { |
41 | 82 | '*androidManagedAppProtection*' { 'Android App Protection' } |
|
47 | 88 | '*defaultManagedAppProtection*' { 'Default App Protection' } |
48 | 89 | default { 'App Protection Policy' } |
49 | 90 | } |
| 91 | + |
| 92 | + # Process assignments |
| 93 | + $PolicyAssignment = [System.Collections.Generic.List[string]]::new() |
| 94 | + $PolicyExclude = [System.Collections.Generic.List[string]]::new() |
| 95 | + $Assignments = $AssignmentResults[$Policy.id] |
| 96 | + if ($Assignments) { |
| 97 | + foreach ($Assignment in $Assignments) { |
| 98 | + $target = $Assignment.target |
| 99 | + switch ($target.'@odata.type') { |
| 100 | + '#microsoft.graph.allDevicesAssignmentTarget' { $PolicyAssignment.Add('All Devices') } |
| 101 | + '#microsoft.graph.allLicensedUsersAssignmentTarget' { $PolicyAssignment.Add('All Licensed Users') } |
| 102 | + '#microsoft.graph.groupAssignmentTarget' { |
| 103 | + $groupName = ($Groups | Where-Object { $_.id -eq $target.groupId }).displayName |
| 104 | + if ($groupName) { $PolicyAssignment.Add($groupName) } |
| 105 | + } |
| 106 | + '#microsoft.graph.exclusionGroupAssignmentTarget' { |
| 107 | + $groupName = ($Groups | Where-Object { $_.id -eq $target.groupId }).displayName |
| 108 | + if ($groupName) { $PolicyExclude.Add($groupName) } |
| 109 | + } |
| 110 | + } |
| 111 | + } |
| 112 | + } |
| 113 | + |
50 | 114 | $Policy | Add-Member -NotePropertyName 'PolicyTypeName' -NotePropertyValue $policyType -Force |
51 | 115 | $Policy | Add-Member -NotePropertyName 'URLName' -NotePropertyValue 'managedAppPolicies' -Force |
52 | 116 | $Policy | Add-Member -NotePropertyName 'PolicySource' -NotePropertyValue 'AppProtection' -Force |
| 117 | + $Policy | Add-Member -NotePropertyName 'PolicyAssignment' -NotePropertyValue ($PolicyAssignment -join ', ') -Force |
| 118 | + $Policy | Add-Member -NotePropertyName 'PolicyExclude' -NotePropertyValue ($PolicyExclude -join ', ') -Force |
53 | 119 | $GraphRequest.Add($Policy) |
54 | 120 | } |
55 | 121 | } |
56 | 122 |
|
57 | | - # Process Mobile App Configurations |
| 123 | + # Process Mobile App Configurations - assignments are already expanded |
58 | 124 | $MobileAppConfigs = ($BulkResults | Where-Object { $_.id -eq 'MobileAppConfigurations' }).body.value |
59 | 125 | if ($MobileAppConfigs) { |
60 | 126 | foreach ($Config in $MobileAppConfigs) { |
|
64 | 130 | '*iosMobileAppConfiguration*' { 'iOS App Configuration' } |
65 | 131 | default { 'App Configuration Policy' } |
66 | 132 | } |
| 133 | + |
| 134 | + # Process assignments |
| 135 | + $PolicyAssignment = [System.Collections.Generic.List[string]]::new() |
| 136 | + $PolicyExclude = [System.Collections.Generic.List[string]]::new() |
| 137 | + if ($Config.assignments) { |
| 138 | + foreach ($Assignment in $Config.assignments) { |
| 139 | + $target = $Assignment.target |
| 140 | + switch ($target.'@odata.type') { |
| 141 | + '#microsoft.graph.allDevicesAssignmentTarget' { $PolicyAssignment.Add('All Devices') } |
| 142 | + '#microsoft.graph.allLicensedUsersAssignmentTarget' { $PolicyAssignment.Add('All Licensed Users') } |
| 143 | + '#microsoft.graph.groupAssignmentTarget' { |
| 144 | + $groupName = ($Groups | Where-Object { $_.id -eq $target.groupId }).displayName |
| 145 | + if ($groupName) { $PolicyAssignment.Add($groupName) } |
| 146 | + } |
| 147 | + '#microsoft.graph.exclusionGroupAssignmentTarget' { |
| 148 | + $groupName = ($Groups | Where-Object { $_.id -eq $target.groupId }).displayName |
| 149 | + if ($groupName) { $PolicyExclude.Add($groupName) } |
| 150 | + } |
| 151 | + } |
| 152 | + } |
| 153 | + } |
| 154 | + |
67 | 155 | $Config | Add-Member -NotePropertyName 'PolicyTypeName' -NotePropertyValue $policyType -Force |
68 | 156 | $Config | Add-Member -NotePropertyName 'URLName' -NotePropertyValue 'mobileAppConfigurations' -Force |
69 | 157 | $Config | Add-Member -NotePropertyName 'PolicySource' -NotePropertyValue 'AppConfiguration' -Force |
| 158 | + $Config | Add-Member -NotePropertyName 'PolicyAssignment' -NotePropertyValue ($PolicyAssignment -join ', ') -Force |
| 159 | + $Config | Add-Member -NotePropertyName 'PolicyExclude' -NotePropertyValue ($PolicyExclude -join ', ') -Force |
70 | 160 |
|
71 | 161 | # Ensure isAssigned property exists for consistency |
72 | 162 | if (-not $Config.PSObject.Properties['isAssigned']) { |
|
0 commit comments