Public/Get-IntuneGroupAssignment.ps1
|
function Get-IntuneGroupAssignment { [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$GroupNames, [Parameter(Mandatory = $false)] [switch]$IncludeNestedGroups, [Parameter(Mandatory = $false)] [switch]$ExportToCSV, [Parameter(Mandatory = $false)] [string]$ExportPath, [Parameter(Mandatory = $false)] [string]$ScopeTagFilter ) Write-Host "Group selection chosen" -ForegroundColor Green # Get Group names from parameter or prompt if ($GroupNames) { $groupInput = $GroupNames } else { # Prompt for Group names or IDs Write-Host "Please enter Group names or Object IDs, separated by commas (,): " -ForegroundColor Cyan Write-Host "Example: 'Marketing Team, 12345678-1234-1234-1234-123456789012'" -ForegroundColor Gray $groupInput = Read-Host } if ([string]::IsNullOrWhiteSpace($groupInput)) { Write-Host "No group information provided. Please try again." -ForegroundColor Red return } $groupInputs = $groupInput -split ',' | ForEach-Object { $_.Trim() } $exportData = [System.Collections.ArrayList]::new() # Determine if nested group checking should be enabled $checkNestedGroups = $false if ($IncludeNestedGroups) { $checkNestedGroups = $true } else { $nestedPrompt = Read-Host "Include assignments inherited from parent groups? (y/n)" if ($nestedPrompt -match '^[Yy]') { $checkNestedGroups = $true } } foreach ($groupInput in $groupInputs) { Write-Host "`nProcessing input: $groupInput" -ForegroundColor Yellow # Initialize variables $groupId = $null $groupName = $null # Check if input is a GUID if ($groupInput -match '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$') { $groupInfo = Get-GroupInfo -GroupId $groupInput if (-not $groupInfo.Success) { Write-Host "No group found with ID: $groupInput" -ForegroundColor Red continue } $groupId = $groupInfo.Id $groupName = $groupInfo.DisplayName } else { # Try to find group by display name $groupUri = "$script:GraphEndpoint/v1.0/groups?`$filter=displayName eq '$groupInput'" $groupResponse = Invoke-MgGraphRequest -Uri $groupUri -Method Get if ($groupResponse.value.Count -eq 0) { Write-Host "No group found with name: $groupInput" -ForegroundColor Red continue } elseif ($groupResponse.value.Count -gt 1) { Write-Host "Multiple groups found with name: $groupInput. Please use the Object ID instead:" -ForegroundColor Red foreach ($group in $groupResponse.value) { Write-Host " - $($group.displayName) (ID: $($group.id))" -ForegroundColor Yellow } continue } $groupId = $groupResponse.value[0].id $groupName = $groupResponse.value[0].displayName } Write-Host "Found group: $groupName (ID: $groupId)" -ForegroundColor Green # Build effective group IDs list (direct + parent groups if nested checking enabled) $allGroupIds = @($groupId) $parentGroupMap = @{} if ($checkNestedGroups) { Write-Host "Checking parent group memberships..." -ForegroundColor Yellow $parentGroups = Get-TransitiveGroupMembership -GroupId $groupId if ($parentGroups.Count -gt 0) { foreach ($pg in $parentGroups) { $allGroupIds += $pg.id $parentGroupMap[$pg.id] = $pg.displayName } Write-Host "Found $($parentGroups.Count) parent group(s): $($parentGroups.displayName -join ', ')" -ForegroundColor Green } else { Write-Host "No parent groups found." -ForegroundColor Gray } } Write-Host "Fetching Intune Profiles and Applications for the group..." -ForegroundColor Yellow # Initialize collections for relevant policies $relevantPolicies = @{ DeviceConfigs = @() SettingsCatalog = @() CompliancePolicies = @() AppProtectionPolicies = @() AppConfigurationPolicies = @() AppsRequired = @() AppsAvailable = @() AppsUninstall = @() PlatformScripts = @() HealthScripts = @() # Endpoint Security profiles AntivirusProfiles = @() DiskEncryptionProfiles = @() FirewallProfiles = @() EndpointDetectionProfiles = @() AttackSurfaceProfiles = @() AccountProtectionProfiles = @() DeploymentProfiles = @() ESPProfiles = @() CloudPCProvisioningPolicies = @() CloudPCUserSettings = @() } # Get Device Configurations Write-Host "Fetching Device Configurations..." -ForegroundColor Yellow $deviceConfigs = Get-IntuneEntities -EntityType "deviceConfigurations" foreach ($config in $deviceConfigs) { $directAssignments = Get-IntuneAssignments -EntityType "deviceConfigurations" -EntityId $config.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $config | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.DeviceConfigs += $config } } } # Get Settings Catalog Policies Write-Host "Fetching Settings Catalog Policies..." -ForegroundColor Yellow $settingsCatalog = Get-IntuneEntities -EntityType "configurationPolicies" foreach ($policy in $settingsCatalog) { # Exclude Windows-only Endpoint Security policies from this generic Settings Catalog fetch # Allow macOS and cross-platform endpoint security policies through if ($policy.templateReference -and $policy.templateReference.templateFamily -like "endpointSecurity*") { $platforms = $policy.platforms # Only skip if this is a Windows-only policy (not macOS or other platforms) if ($platforms -and (($platforms -contains "windows10" -or $platforms -contains "windows10AndLater") -and $platforms -notcontains "macOS")) { continue } } $directAssignments = Get-IntuneAssignments -EntityType "configurationPolicies" -EntityId $policy.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $policy | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.SettingsCatalog += $policy } } } # Get Compliance Policies Write-Host "Fetching Compliance Policies..." -ForegroundColor Yellow $compliancePolicies = Get-IntuneEntities -EntityType "deviceCompliancePolicies" foreach ($policy in $compliancePolicies) { $directAssignments = Get-IntuneAssignments -EntityType "deviceCompliancePolicies" -EntityId $policy.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $policy | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.CompliancePolicies += $policy } } } # Get App Protection Policies Write-Host "Fetching App Protection Policies..." -ForegroundColor Yellow $appProtectionPolicies = Get-IntuneEntities -EntityType "deviceAppManagement/managedAppPolicies" foreach ($policy in $appProtectionPolicies) { # Get-IntuneAssignments handles App Protection policy type resolution internally try { $directAssignments = Get-IntuneAssignments -EntityType "deviceAppManagement/managedAppPolicies" -EntityId $policy.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $policy | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.AppProtectionPolicies += $policy } } } catch { Write-Host "Error fetching assignments for App Protection policy $($policy.displayName): $($_.Exception.Message)" -ForegroundColor Red } } # Get App Configuration Policies Write-Host "Fetching App Configuration Policies..." -ForegroundColor Yellow $appConfigPolicies = Get-IntuneEntities -EntityType "deviceAppManagement/mobileAppConfigurations" foreach ($policy in $appConfigPolicies) { $directAssignments = Get-IntuneAssignments -EntityType "mobileAppConfigurations" -EntityId $policy.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $policy | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.AppConfigurationPolicies += $policy } } } # Endpoint Security Policies for the specific group $endpointSecurityCategories = @( @{ Name = "Antivirus"; Key = "AntivirusProfiles"; TemplateFamily = "endpointSecurityAntivirus"; UserFriendlyType = "Antivirus Profile" }, @{ Name = "Disk Encryption"; Key = "DiskEncryptionProfiles"; TemplateFamily = "endpointSecurityDiskEncryption"; UserFriendlyType = "Disk Encryption Profile" }, @{ Name = "Firewall"; Key = "FirewallProfiles"; TemplateFamily = "endpointSecurityFirewall"; UserFriendlyType = "Firewall Profile" }, @{ Name = "Endpoint Detection and Response"; Key = "EndpointDetectionProfiles"; TemplateFamily = "endpointSecurityEndpointDetectionAndResponse"; UserFriendlyType = "EDR Profile" }, @{ Name = "Attack Surface Reduction"; Key = "AttackSurfaceProfiles"; TemplateFamily = "endpointSecurityAttackSurfaceReduction"; UserFriendlyType = "ASR Profile" }, @{ Name = "Account Protection"; Key = "AccountProtectionProfiles"; TemplateFamily = "endpointSecurityAccountProtection"; UserFriendlyType = "Account Protection Profile" } ) foreach ($esCategory in $endpointSecurityCategories) { Write-Host "Fetching $($esCategory.Name) Policies for group..." -ForegroundColor Yellow $processedEsPolicyIds = [System.Collections.Generic.HashSet[string]]::new() # Track IDs per category to avoid duplicates from configPolicies and intents # 1. Check configurationPolicies (Settings Catalog style ES policies) $allConfigEsPolicies = Get-IntuneEntities -EntityType "configurationPolicies" # Fetch all, then filter $matchingConfigEsPolicies = $allConfigEsPolicies | Where-Object { $_.templateReference -and $_.templateReference.templateFamily -eq $esCategory.TemplateFamily } if ($matchingConfigEsPolicies) { foreach ($policy in $matchingConfigEsPolicies) { if ($processedEsPolicyIds.Add($policy.id)) { $directAssignments = Get-IntuneAssignments -EntityType "configurationPolicies" -EntityId $policy.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $policy | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies[$esCategory.Key] += $policy } } } } } # 2. Check deviceManagement/intents (Template style ES policies) $allIntentEsPolicies = Get-IntuneEntities -EntityType "deviceManagement/intents" # Fetch all, then filter Add-IntentTemplateFamilyInfo -IntentPolicies $allIntentEsPolicies $matchingIntentEsPolicies = $allIntentEsPolicies | Where-Object { $_.templateReference -and $_.templateReference.templateFamily -eq $esCategory.TemplateFamily } if ($matchingIntentEsPolicies) { foreach ($policy in $matchingIntentEsPolicies) { if ($processedEsPolicyIds.Add($policy.id)) { # For intents, assignments are fetched differently try { $allIntentAssignments = [System.Collections.ArrayList]::new() $currentIntentAssignmentsUri = "$script:GraphEndpoint/beta/deviceManagement/intents/$($policy.id)/assignments" do { $intentAssignmentsResponsePage = Invoke-MgGraphRequest -Uri $currentIntentAssignmentsUri -Method Get if ($intentAssignmentsResponsePage -and $null -ne $intentAssignmentsResponsePage.value) { $allIntentAssignments.AddRange($intentAssignmentsResponsePage.value) } $currentIntentAssignmentsUri = $intentAssignmentsResponsePage.'@odata.nextLink' } while (![string]::IsNullOrEmpty($currentIntentAssignmentsUri)) $assignmentReasons = @() foreach ($intentAssignment in $allIntentAssignments) { $targetGid = $intentAssignment.target.groupId if ($intentAssignment.target.'@odata.type' -eq '#microsoft.graph.exclusionGroupAssignmentTarget' -and $allGroupIds -contains $targetGid) { if ($targetGid -eq $groupId) { $assignmentReasons += "Direct Exclusion" } elseif ($parentGroupMap.ContainsKey($targetGid)) { $assignmentReasons += "Inherited Exclusion (via $($parentGroupMap[$targetGid]))" } } elseif ($intentAssignment.target.'@odata.type' -eq '#microsoft.graph.groupAssignmentTarget' -and $allGroupIds -contains $targetGid) { if ($targetGid -eq $groupId) { $assignmentReasons += "Direct Assignment" } elseif ($parentGroupMap.ContainsKey($targetGid)) { $assignmentReasons += "Inherited (via $($parentGroupMap[$targetGid]))" } } } if ($assignmentReasons.Count -gt 0) { $policy | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies[$esCategory.Key] += $policy } } catch { Write-Warning "Error fetching assignments for ES Intent $($policy.displayName) (ID: $($policy.id)): $($_.Exception.Message)" } } } } } # Fetch and process Applications Write-Host "Fetching Applications..." -ForegroundColor Yellow $appUri = "$script:GraphEndpoint/beta/deviceAppManagement/mobileApps?`$filter=isAssigned eq true" $appResponse = Invoke-MgGraphRequest -Uri $appUri -Method Get $allApps = $appResponse.value while ($appResponse.'@odata.nextLink') { $appResponse = Invoke-MgGraphRequest -Uri $appResponse.'@odata.nextLink' -Method Get $allApps += $appResponse.value } $totalApps = $allApps.Count foreach ($app in $allApps) { # Filter out irrelevant apps if ($app.isFeatured -or $app.isBuiltIn) { continue } $appId = $app.id $allAppAssignments = [System.Collections.ArrayList]::new() $currentAppAssignmentsUri = "$script:GraphEndpoint/beta/deviceAppManagement/mobileApps('$appId')/assignments" do { $appAssignmentsResponsePage = Invoke-MgGraphRequest -Uri $currentAppAssignmentsUri -Method Get if ($appAssignmentsResponsePage -and $null -ne $appAssignmentsResponsePage.value) { $allAppAssignments.AddRange($appAssignmentsResponsePage.value) } $currentAppAssignmentsUri = $appAssignmentsResponsePage.'@odata.nextLink' } while (![string]::IsNullOrEmpty($currentAppAssignmentsUri)) $relevantAppAssignmentReasons = @() $intentForGroup = $null foreach ($assignmentItem in $allAppAssignments) { $appTargetGid = $assignmentItem.target.groupId if ($assignmentItem.target.'@odata.type' -eq '#microsoft.graph.groupAssignmentTarget' -and $allGroupIds -contains $appTargetGid) { if ($appTargetGid -eq $groupId) { $relevantAppAssignmentReasons += "Direct Assignment" } elseif ($parentGroupMap.ContainsKey($appTargetGid)) { $relevantAppAssignmentReasons += "Inherited (via $($parentGroupMap[$appTargetGid]))" } if (-not $intentForGroup) { $intentForGroup = $assignmentItem.intent } } elseif ($assignmentItem.target.'@odata.type' -eq '#microsoft.graph.exclusionGroupAssignmentTarget' -and $allGroupIds -contains $appTargetGid) { if ($appTargetGid -eq $groupId) { $relevantAppAssignmentReasons += "Group Exclusion" } elseif ($parentGroupMap.ContainsKey($appTargetGid)) { $relevantAppAssignmentReasons += "Inherited Exclusion (via $($parentGroupMap[$appTargetGid]))" } } } if ($relevantAppAssignmentReasons.Count -gt 0) { $appWithReason = $app.PSObject.Copy() $appWithReason | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($relevantAppAssignmentReasons -join "; ") -Force if ($intentForGroup) { switch ($intentForGroup) { "required" { $relevantPolicies.AppsRequired += $appWithReason } "available" { $relevantPolicies.AppsAvailable += $appWithReason } "uninstall" { $relevantPolicies.AppsUninstall += $appWithReason } } } } } # Get Platform Scripts Write-Host "Fetching Platform Scripts..." -ForegroundColor Yellow $platformScripts = Get-IntuneEntities -EntityType "deviceManagementScripts" foreach ($script in $platformScripts) { $directAssignments = Get-IntuneAssignments -EntityType "deviceManagementScripts" -EntityId $script.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $script | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.PlatformScripts += $script } } } # Get Proactive Remediation Scripts Write-Host "Fetching Proactive Remediation Scripts..." -ForegroundColor Yellow $healthScripts = Get-IntuneEntities -EntityType "deviceHealthScripts" foreach ($script in $healthScripts) { $directAssignments = Get-IntuneAssignments -EntityType "deviceHealthScripts" -EntityId $script.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $script | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.HealthScripts += $script } } } # Get Autopilot Deployment Profiles Write-Host "Fetching Autopilot Deployment Profiles..." -ForegroundColor Yellow $autoProfiles = Get-IntuneEntities -EntityType "windowsAutopilotDeploymentProfiles" foreach ($policyProfile in $autoProfiles) { $directAssignments = Get-IntuneAssignments -EntityType "windowsAutopilotDeploymentProfiles" -EntityId $policyProfile.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $policyProfile | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.DeploymentProfiles += $policyProfile } } } # Get Enrollment Status Page Profiles Write-Host "Fetching Enrollment Status Page Profiles..." -ForegroundColor Yellow $enrollmentConfigs = Get-IntuneEntities -EntityType "deviceEnrollmentConfigurations" $espProfiles = $enrollmentConfigs | Where-Object { $_.'@odata.type' -match 'EnrollmentCompletionPageConfiguration' } foreach ($esp in $espProfiles) { $directAssignments = Get-IntuneAssignments -EntityType "deviceEnrollmentConfigurations" -EntityId $esp.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $esp | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.ESPProfiles += $esp } } } # Get Windows 365 Cloud PC Provisioning Policies Write-Host "Fetching Windows 365 Cloud PC Provisioning Policies..." -ForegroundColor Yellow try { $cloudPCProvisioningPolicies = Get-IntuneEntities -EntityType "virtualEndpoint/provisioningPolicies" foreach ($policy in $cloudPCProvisioningPolicies) { $directAssignments = Get-IntuneAssignments -EntityType "virtualEndpoint/provisioningPolicies" -EntityId $policy.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $policy | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.CloudPCProvisioningPolicies += $policy } } } } catch { Write-Verbose "Skipping - Windows 365 may not be licensed for this tenant" } # Get Windows 365 Cloud PC User Settings Write-Host "Fetching Windows 365 Cloud PC User Settings..." -ForegroundColor Yellow try { $cloudPCUserSettings = Get-IntuneEntities -EntityType "virtualEndpoint/userSettings" foreach ($setting in $cloudPCUserSettings) { $directAssignments = Get-IntuneAssignments -EntityType "virtualEndpoint/userSettings" -EntityId $setting.id -GroupIds $allGroupIds if ($directAssignments.Count -gt 0) { $assignmentReasons = Get-GroupAssignmentReasons -Assignments $directAssignments -DirectGroupId $groupId -ParentGroupMap $parentGroupMap if ($assignmentReasons.Count -gt 0) { $setting | Add-Member -NotePropertyName 'AssignmentReason' -NotePropertyValue ($assignmentReasons -join "; ") -Force $relevantPolicies.CloudPCUserSettings += $setting } } } } catch { Write-Verbose "Skipping - Windows 365 may not be licensed for this tenant" } # Apply scope tag filter if specified if ($ScopeTagFilter) { foreach ($key in @($relevantPolicies.Keys)) { $relevantPolicies[$key] = @(Filter-ByScopeTag -Items $relevantPolicies[$key] -FilterTag $ScopeTagFilter -ScopeTagLookup $script:ScopeTagLookup) } } # Function to format and display policy table (specific to Option 2) function Format-PolicyTable { param ( [string]$Title, [object[]]$Policies, [scriptblock]$GetName ) $localTableSeparator = Get-Separator # Create prominent section header $headerSeparator = "-" * ($Title.Length + 16) Write-Host "`n$headerSeparator" -ForegroundColor Cyan Write-Host "------- $Title -------" -ForegroundColor Cyan Write-Host "$headerSeparator" -ForegroundColor Cyan if ($Policies.Count -eq 0) { Write-Host "No $Title found for this group." -ForegroundColor Gray Write-Host $localTableSeparator -ForegroundColor Gray Write-Host "" return } # Create table header $headerFormat = "{0,-40} {1,-15} {2,-20} {3,-30} {4,-35}" -f "Policy Name", "Platform", "Scope Tags", "ID", "Assignment" Write-Host $headerFormat -ForegroundColor Yellow Write-Host $localTableSeparator -ForegroundColor Gray # Display each policy foreach ($policy in $Policies) { $name = & $GetName $policy if ($name.Length -gt 37) { $name = $name.Substring(0, 34) + "..." } $platform = Get-PolicyPlatform -Policy $policy if ($platform.Length -gt 12) { $platform = $platform.Substring(0, 9) + "..." } $scopeTags = Get-ScopeTagNames -ScopeTagIds $policy.roleScopeTagIds -ScopeTagLookup $script:ScopeTagLookup if ($scopeTags.Length -gt 17) { $scopeTags = $scopeTags.Substring(0, 14) + "..." } $id = $policy.id if ($id.Length -gt 27) { $id = $id.Substring(0, 24) + "..." } $assignment = if ($policy.AssignmentReason) { $policy.AssignmentReason } else { "N/A" } if ($assignment.Length -gt 32) { $assignment = $assignment.Substring(0, 29) + "..." } $rowFormat = "{0,-40} {1,-15} {2,-20} {3,-30} {4,-35}" -f $name, $platform, $scopeTags, $id, $assignment if ($assignment -match "Inherited Exclusion") { Write-Host $rowFormat -ForegroundColor Magenta } elseif ($assignment -match "Direct Exclusion") { Write-Host $rowFormat -ForegroundColor Red } elseif ($assignment -match "Inherited") { Write-Host $rowFormat -ForegroundColor DarkYellow } else { Write-Host $rowFormat -ForegroundColor White } } Write-Host $localTableSeparator -ForegroundColor Gray } # Display Device Configurations Format-PolicyTable -Title "Device Configurations" -Policies $relevantPolicies.DeviceConfigs -GetName { param($config) if ([string]::IsNullOrWhiteSpace($config.name)) { $config.displayName } else { $config.name } } # Display Settings Catalog Policies Format-PolicyTable -Title "Settings Catalog Policies" -Policies $relevantPolicies.SettingsCatalog -GetName { param($policy) if ([string]::IsNullOrWhiteSpace($policy.name)) { $policy.displayName } else { $policy.name } } # Display Compliance Policies Format-PolicyTable -Title "Compliance Policies" -Policies $relevantPolicies.CompliancePolicies -GetName { param($policy) if ([string]::IsNullOrWhiteSpace($policy.name)) { $policy.displayName } else { $policy.name } } # Display App Protection Policies Format-PolicyTable -Title "App Protection Policies" -Policies $relevantPolicies.AppProtectionPolicies -GetName { param($policy) $policy.displayName } -GetExtra { param($policy) @{ Label = 'Platform' Value = switch ($policy.'@odata.type') { "#microsoft.graph.androidManagedAppProtection" { "Android" } "#microsoft.graph.iosManagedAppProtection" { "iOS" } "#microsoft.graph.windowsManagedAppProtection" { "Windows" } default { "Unknown" } } } } # Display App Configuration Policies Format-PolicyTable -Title "App Configuration Policies" -Policies $relevantPolicies.AppConfigurationPolicies -GetName { param($policy) if ([string]::IsNullOrWhiteSpace($policy.name)) { $policy.displayName } else { $policy.name } } # Display Platform Scripts Format-PolicyTable -Title "Platform Scripts" -Policies $relevantPolicies.PlatformScripts -GetName { param($script) if ([string]::IsNullOrWhiteSpace($script.name)) { $script.displayName } else { $script.name } } # Display Proactive Remediation Scripts Format-PolicyTable -Title "Proactive Remediation Scripts" -Policies $relevantPolicies.HealthScripts -GetName { param($script) if ([string]::IsNullOrWhiteSpace($script.name)) { $script.displayName } else { $script.name } } # Display Autopilot Deployment Profiles Format-PolicyTable -Title "Autopilot Deployment Profiles" -Policies $relevantPolicies.DeploymentProfiles -GetName { param($policyProfile) if ([string]::IsNullOrWhiteSpace($policyProfile.displayName)) { $policyProfile.name } else { $policyProfile.displayName } } # Display Enrollment Status Page Profiles Format-PolicyTable -Title "Enrollment Status Page Profiles" -Policies $relevantPolicies.ESPProfiles -GetName { param($policyProfile) if ([string]::IsNullOrWhiteSpace($policyProfile.displayName)) { $policyProfile.name } else { $policyProfile.displayName } } # Display Windows 365 Cloud PC Provisioning Policies Format-PolicyTable -Title "Windows 365 Cloud PC Provisioning Policies" -Policies $relevantPolicies.CloudPCProvisioningPolicies -GetName { param($policy) if ([string]::IsNullOrWhiteSpace($policy.displayName)) { $policy.name } else { $policy.displayName } } # Display Windows 365 Cloud PC User Settings Format-PolicyTable -Title "Windows 365 Cloud PC User Settings" -Policies $relevantPolicies.CloudPCUserSettings -GetName { param($setting) if ([string]::IsNullOrWhiteSpace($setting.displayName)) { $setting.name } else { $setting.displayName } } # Display Required Apps Format-PolicyTable -Title "Required Apps" -Policies $relevantPolicies.AppsRequired -GetName { param($app) $app.displayName } # Display Available Apps Format-PolicyTable -Title "Available Apps" -Policies $relevantPolicies.AppsAvailable -GetName { param($app) $app.displayName } # Display Uninstall Apps Format-PolicyTable -Title "Uninstall Apps" -Policies $relevantPolicies.AppsUninstall -GetName { param($app) $app.displayName } # Display Endpoint Security - Antivirus Profiles Format-PolicyTable -Title "Endpoint Security - Antivirus Profiles" -Policies $relevantPolicies.AntivirusProfiles -GetName { param($policyProfile) if (-not [string]::IsNullOrWhiteSpace($policyProfile.displayName)) { $policyProfile.displayName } elseif (-not [string]::IsNullOrWhiteSpace($policyProfile.name)) { $policyProfile.name } else { "Unnamed Profile" } } # Display Endpoint Security - Disk Encryption Profiles Format-PolicyTable -Title "Endpoint Security - Disk Encryption Profiles" -Policies $relevantPolicies.DiskEncryptionProfiles -GetName { param($policyProfile) if (-not [string]::IsNullOrWhiteSpace($policyProfile.displayName)) { $policyProfile.displayName } elseif (-not [string]::IsNullOrWhiteSpace($policyProfile.name)) { $policyProfile.name } else { "Unnamed Profile" } } # Display Endpoint Security - Firewall Profiles Format-PolicyTable -Title "Endpoint Security - Firewall Profiles" -Policies $relevantPolicies.FirewallProfiles -GetName { param($policyProfile) if (-not [string]::IsNullOrWhiteSpace($policyProfile.displayName)) { $policyProfile.displayName } elseif (-not [string]::IsNullOrWhiteSpace($policyProfile.name)) { $policyProfile.name } else { "Unnamed Profile" } } # Display Endpoint Security - Endpoint Detection and Response Profiles Format-PolicyTable -Title "Endpoint Security - EDR Profiles" -Policies $relevantPolicies.EndpointDetectionProfiles -GetName { param($policyProfile) if (-not [string]::IsNullOrWhiteSpace($policyProfile.displayName)) { $policyProfile.displayName } elseif (-not [string]::IsNullOrWhiteSpace($policyProfile.name)) { $policyProfile.name } else { "Unnamed Profile" } } # Display Endpoint Security - Attack Surface Reduction Profiles Format-PolicyTable -Title "Endpoint Security - ASR Profiles" -Policies $relevantPolicies.AttackSurfaceProfiles -GetName { param($policyProfile) if (-not [string]::IsNullOrWhiteSpace($policyProfile.displayName)) { $policyProfile.displayName } elseif (-not [string]::IsNullOrWhiteSpace($policyProfile.name)) { $policyProfile.name } else { "Unnamed Profile" } } # Display Endpoint Security - Account Protection Profiles Format-PolicyTable -Title "Endpoint Security - Account Protection Profiles" -Policies $relevantPolicies.AccountProtectionProfiles -GetName { param($policyProfile) if (-not [string]::IsNullOrWhiteSpace($policyProfile.displayName)) { $policyProfile.displayName } elseif (-not [string]::IsNullOrWhiteSpace($policyProfile.name)) { $policyProfile.name } else { "Unnamed Profile" } } # Add to export data Add-ExportData -ExportData $exportData -Category "Device" -Items @([PSCustomObject]@{ displayName = $deviceName id = $deviceInfo.Id AssignmentReason = "N/A" } Add-ExportData -ExportData $exportData -Category "Device Configuration" -Items $relevantPolicies.DeviceConfigs -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Settings Catalog Policy" -Items $relevantPolicies.SettingsCatalog -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Compliance Policy" -Items $relevantPolicies.CompliancePolicies -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "App Protection Policy" -Items $relevantPolicies.AppProtectionPolicies -AssignmentReason { param($item) $item.AssignmentSummary } Add-ExportData -ExportData $exportData -Category "App Configuration Policy" -Items $relevantPolicies.AppConfigurationPolicies -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Platform Scripts" -Items $relevantPolicies.PlatformScripts -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Proactive Remediation Scripts" -Items $relevantPolicies.HealthScripts -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Autopilot Deployment Profile" -Items $relevantPolicies.DeploymentProfiles -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Enrollment Status Page" -Items $relevantPolicies.ESPProfiles -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Windows 365 Cloud PC Provisioning Policy" -Items $relevantPolicies.CloudPCProvisioningPolicies -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Windows 365 Cloud PC User Setting" -Items $relevantPolicies.CloudPCUserSettings -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Endpoint Security - Antivirus" -Items $relevantPolicies.AntivirusProfiles -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Endpoint Security - Disk Encryption" -Items $relevantPolicies.DiskEncryptionProfiles -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Endpoint Security - Firewall" -Items $relevantPolicies.FirewallProfiles -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Endpoint Security - EDR" -Items $relevantPolicies.EndpointDetectionProfiles -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Endpoint Security - ASR" -Items $relevantPolicies.AttackSurfaceProfiles -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Endpoint Security - Account Protection" -Items $relevantPolicies.AccountProtectionProfiles -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Required Apps" -Items $relevantPolicies.AppsRequired -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Available Apps" -Items $relevantPolicies.AppsAvailable -AssignmentReason { param($item) $item.AssignmentReason } Add-ExportData -ExportData $exportData -Category "Uninstall Apps" -Items $relevantPolicies.AppsUninstall -AssignmentReason { param($item) $item.AssignmentReason } ) } # Export results if requested Export-ResultsIfRequested -ExportData $exportData -DefaultFileName "IntuneGroupAssignments.csv" -ForceExport:$ExportToCSV -CustomExportPath $ExportPath } |