Src/Private/Get-AbrIntuneConfigurationProfiles.ps1

function Get-AbrIntuneConfigurationProfiles {
    [CmdletBinding()]
    param ([Parameter(Position = 0, Mandatory)][string]$TenantId)

    begin {
        Write-PScriboMessage -Message "Collecting Intune Configuration Profiles for $TenantId."
        Show-AbrDebugExecutionTime -Start -TitleMessage 'Configuration Profiles'
    }

    process {
        Section -Style Heading2 'Configuration Profiles' {
            Paragraph "The following section documents the Device Configuration Profiles configured in tenant $TenantId."
            BlankLine

            $TotalConfigProfiles      = 0
            $UnassignedConfigProfiles = 0
            $TotalSettingsCatalog     = 0
            $TotalAdminTemplates      = 0
            $TotalSecurityBaselines   = if ($null -ne $script:TotalSecurityBaselines) { $script:TotalSecurityBaselines } else { 0 }

            #region Legacy Device Configuration Profiles
            try {
                Write-Host " - Retrieving device configuration profiles..."
                $ProfilesResp = Invoke-MgGraphRequest -Method GET `
                    -Uri "$($script:GraphEndpoint)/v1.0/deviceManagement/deviceConfigurations?$expand=assignments" `
                    -ErrorAction Stop
                $Profiles = $ProfilesResp.value

                if ($Profiles -and @($Profiles).Count -gt 0) {
                    $null = ($TotalConfigProfiles = @($Profiles).Count)
                    Section -Style Heading3 'Device Configuration Profiles' {
                        BlankLine
                        $ProfObj = [System.Collections.ArrayList]::new()
                        foreach ($Profile in ($Profiles | Sort-Object displayName)) {
                            $OdataType = $Profile.'@odata.type' -replace '#microsoft.graph.', ''
                            $Platform  = switch -Wildcard ($OdataType) {
                                '*Windows*' { 'Windows' } '*Ios*' { 'iOS / iPadOS' } '*Android*' { 'Android' }
                                '*MacOs*'   { 'macOS'   } '*Edge*'{ 'Edge'         } default { $OdataType }
                            }
                            $assignResolved = Resolve-IntuneAssignments -Assignments $Profile.assignments -CheckMemberCount:$script:CheckEmptyGroups
                            $AssignedTo = $assignResolved.AssignmentSummary
                            if ($assignResolved.AssignmentSummary -eq 'Not assigned') { $null = ($UnassignedConfigProfiles++) }
                            $ProfObj.Add([pscustomobject]([ordered]@{
                                'Profile Name'  = $Profile.displayName
                                'Platform'      = $Platform
                                'Profile Type'  = $OdataType
                                'Assignments'   = $AssignedTo
                                'Last Modified' = if ($Profile.lastModifiedDateTime) { ([datetime]$Profile.lastModifiedDateTime).ToString('yyyy-MM-dd') } else { '--' }
                            })) | Out-Null
                        }
                        $null = (& { if ($HealthCheck.Intune.ConfigurationProfiles) { $null = ($ProfObj | Where-Object { $_.'Assignments' -eq 'Not assigned' } | Set-Style -Style Warning | Out-Null) } })
                        $ProfTableParams = @{ Name = "Device Configuration Profiles - $TenantId"; ColumnWidths = 25, 14, 22, 22, 17 }
                        if ($Report.ShowTableCaptions) { $ProfTableParams['Caption'] = "- $($ProfTableParams.Name)" }
                        $ProfObj | Table @ProfTableParams
                        if (Get-IntuneExcelSheetEnabled -SheetKey 'ConfigProfiles') { $script:ExcelSheets['Config Profiles'] = $ProfObj }
                        if (Get-IntuneBackupSectionEnabled -SectionKey 'ConfigurationProfiles') { $script:BackupData['ConfigurationProfiles'] = $Profiles }
                    }
                }
            } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'Device Configuration Profiles' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'Device Configuration Profiles' -Message "$($_.Exception.Message)" } }
            #endregion

            #region Settings Catalog
            try {
                Write-Host " - Retrieving Settings Catalog policies..."
                # /beta required - v1.0 configurationPolicies does not support $expand=assignments
                $CatalogResp = Invoke-MgGraphRequest -Method GET -Uri "$($script:GraphEndpoint)/beta/deviceManagement/configurationPolicies?$expand=assignments" -ErrorAction SilentlyContinue
                $CatalogPolicies = $CatalogResp.value
                if ($CatalogPolicies -and @($CatalogPolicies).Count -gt 0) {
                    $null = ($TotalSettingsCatalog = @($CatalogPolicies).Count)
                    Section -Style Heading3 'Settings Catalog Policies' {
                        BlankLine
                        $CatObj = [System.Collections.ArrayList]::new()
                        foreach ($CatPolicy in ($CatalogPolicies | Sort-Object name)) {
                            $Platform = switch ($CatPolicy.platforms) {
                                'windows10' { 'Windows 10/11' } 'macOS' { 'macOS' } 'iOS' { 'iOS / iPadOS' }
                                'android'   { 'Android'       } default { if ($CatPolicy.platforms) { $CatPolicy.platforms } else { '--' } }
                            }
                            $assignResolved = Resolve-IntuneAssignments -Assignments $CatPolicy.assignments -CheckMemberCount:$script:CheckEmptyGroups
                            $AssignedTo = $assignResolved.AssignmentSummary
                            if ($assignResolved.AssignmentSummary -eq 'Not assigned') { $null = ($UnassignedConfigProfiles++) }
                            $CatObj.Add([pscustomobject]([ordered]@{
                                'Policy Name'   = $CatPolicy.name
                                'Platform'      = $Platform
                                'Technology'    = if ($CatPolicy.technologies) { $CatPolicy.technologies } else { '--' }
                                'Assignments'   = $AssignedTo
                                'Last Modified' = if ($CatPolicy.lastModifiedDateTime) { ([datetime]$CatPolicy.lastModifiedDateTime).ToString('yyyy-MM-dd') } else { '--' }
                            })) | Out-Null
                        }
                        $null = (& { if ($HealthCheck.Intune.ConfigurationProfiles) { $null = ($CatObj | Where-Object { $_.'Assignments' -eq 'Not assigned' } | Set-Style -Style Warning | Out-Null) } })
                        $CatTableParams = @{ Name = "Settings Catalog Policies - $TenantId"; ColumnWidths = 28, 16, 20, 20, 16 }
                        if ($Report.ShowTableCaptions) { $CatTableParams['Caption'] = "- $($CatTableParams.Name)" }
                        $CatObj | Table @CatTableParams
                        if (Get-IntuneExcelSheetEnabled -SheetKey 'SettingsCatalog') { $script:ExcelSheets['Settings Catalog'] = $CatObj }
                        if (Get-IntuneBackupSectionEnabled -SectionKey 'SettingsCatalog') { $script:BackupData['SettingsCatalog'] = $CatalogPolicies }
                    }
                }
            } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'Settings Catalog Policies' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'Settings Catalog Policies' -Message "$($_.Exception.Message)" } }
            #endregion

            #region Administrative Templates
            try {
                Write-Host " - Retrieving Administrative Templates..."
                # /beta required - v1.0 groupPolicyConfigurations does not support $expand=assignments
                $GPResp = Invoke-MgGraphRequest -Method GET -Uri "$($script:GraphEndpoint)/beta/deviceManagement/groupPolicyConfigurations?$expand=assignments" -ErrorAction SilentlyContinue
                $GPPolicies = $GPResp.value
                if ($GPPolicies -and @($GPPolicies).Count -gt 0) {
                    $null = ($TotalAdminTemplates = @($GPPolicies).Count)
                    Section -Style Heading3 'Administrative Templates' {
                        BlankLine
                        $GPObj = [System.Collections.ArrayList]::new()
                        foreach ($GPPolicy in ($GPPolicies | Sort-Object displayName)) {
                            $assignResolved = Resolve-IntuneAssignments -Assignments $GPPolicy.assignments -CheckMemberCount:$script:CheckEmptyGroups
                            $AssignedTo = $assignResolved.AssignmentSummary
                            if ($assignResolved.AssignmentSummary -eq 'Not assigned') { $null = ($UnassignedConfigProfiles++) }
                            $GPObj.Add([pscustomobject]([ordered]@{
                                'Policy Name'   = $GPPolicy.displayName
                                'Description'   = if ($GPPolicy.description) { $GPPolicy.description } else { '--' }
                                'Assignments'   = $AssignedTo
                                'Last Modified' = if ($GPPolicy.lastModifiedDateTime) { ([datetime]$GPPolicy.lastModifiedDateTime).ToString('yyyy-MM-dd') } else { '--' }
                            })) | Out-Null
                        }
                        $null = (& { if ($HealthCheck.Intune.ConfigurationProfiles) { $null = ($GPObj | Where-Object { $_.'Assignments' -eq 'Not assigned' } | Set-Style -Style Warning | Out-Null) } })
                        $GPTableParams = @{ Name = "Administrative Templates - $TenantId"; ColumnWidths = 28, 32, 22, 18 }
                        if ($Report.ShowTableCaptions) { $GPTableParams['Caption'] = "- $($GPTableParams.Name)" }
                        $GPObj | Table @GPTableParams
                        if (Get-IntuneExcelSheetEnabled -SheetKey 'AdminTemplates') { $script:ExcelSheets['Admin Templates'] = $GPObj }
                        if (Get-IntuneBackupSectionEnabled -SectionKey 'AdminTemplates') { $script:BackupData['AdminTemplates'] = $GPPolicies }
                    }
                }
            } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'Administrative Templates' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'Administrative Templates' -Message "$($_.Exception.Message)" } }
            #endregion

            # Share total for use in Invoke function
            $null = ($script:TotalConfigProfilesAll = $TotalConfigProfiles + $TotalSettingsCatalog + $TotalAdminTemplates)

            #region ACSC E8 Assessment
            if ($script:IncludeACSCe8) {
                BlankLine
                Paragraph "ACSC Essential Eight Maturity Level Assessment -- Configuration Profiles:"
                BlankLine
                try {
                    $_v = @{
                        TotalConfigProfiles      = $script:TotalConfigProfilesAll
                        UnassignedConfigProfiles = $UnassignedConfigProfiles
                        TotalSettingsCatalog     = $TotalSettingsCatalog
                        TotalAdminTemplates      = $TotalAdminTemplates
                        TotalSecurityBaselines   = $TotalSecurityBaselines
                    }
                    $E8Checks = Build-AbrIntuneComplianceChecks -Definitions (Get-AbrIntuneE8Checks -Section 'ConfigurationProfiles') -Framework E8 -CallerVariables $_v
                    New-AbrIntuneE8AssessmentTable -Checks $E8Checks -Name 'Configuration Profiles' -TenantId $TenantId
                    if ($E8Checks) { $null = $script:E8AllChecks.AddRange([object[]](@($E8Checks | Select-Object @{N='Section';E={'ConfigurationProfiles'}}, ML, Control, Status, Detail))) }
                } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'E8 Configuration Profiles Assessment' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'E8 Configuration Profiles Assessment' -Message "$($_.Exception.Message)" } }
            }
            #endregion

            #region CIS Assessment
            if ($script:IncludeCISBaseline) {
                BlankLine
                Paragraph "CIS Microsoft 365 Foundations Benchmark Assessment -- Configuration Profiles:"
                BlankLine
                try {
                    $_v = @{
                        TotalConfigProfiles      = $script:TotalConfigProfilesAll
                        UnassignedConfigProfiles = $UnassignedConfigProfiles
                        TotalSecurityBaselines   = $TotalSecurityBaselines
                    }
                    $CISChecks = Build-AbrIntuneComplianceChecks -Definitions (Get-AbrIntuneCISChecks -Section 'ConfigurationProfiles') -Framework CIS -CallerVariables $_v
                    New-AbrIntuneCISAssessmentTable -Checks $CISChecks -Name 'Configuration Profiles' -TenantId $TenantId
                    if ($CISChecks) { $null = $script:CISAllChecks.AddRange([object[]](@($CISChecks | Select-Object @{N='Section';E={'ConfigurationProfiles'}}, CISControl, Level, Status, Detail))) }
                } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'CIS Configuration Profiles Assessment' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'CIS Configuration Profiles Assessment' -Message "$($_.Exception.Message)" } }
            }
            #endregion
        }
    }

    end { Show-AbrDebugExecutionTime -End -TitleMessage 'Configuration Profiles' }
}