Src/Private/Get-AbrIntuneDefenderForCloudApps.ps1

function Get-AbrIntuneDefenderForCloudApps {
    <#
    .SYNOPSIS
    Documents Microsoft Defender for Cloud Apps (MDCA) integration and configuration.
    .DESCRIPTION
        Collects and reports on:
          - MDCA data sources configured in the tenant
          - MDE integration for continuous shadow IT discovery
          - Products and components in scope
          - Discovery architecture mode (continuous vs snapshot)
          - Connected API-enabled cloud apps
        Queries the security Graph API for MCAS/MDCA settings and MDE integration status.
    .NOTES
        Version: 0.1.0
        Author: Pai Wei Sing
        Required Scopes: SecurityEvents.Read.All, CloudApp.Read.All (if available)
    #>

    [CmdletBinding()]
    param (
        [Parameter(Position = 0, Mandatory)]
        [string]$TenantId
    )

    begin {
        Write-PScriboMessage -Message "Collecting Microsoft Defender for Cloud Apps configuration for $TenantId."
        Show-AbrDebugExecutionTime -Start -TitleMessage 'Defender for Cloud Apps'
    }

    process {

        # ── Products in Scope ───────────────────────────────────────────────────
        try {
            Write-Host " - Retrieving Microsoft Defender for Cloud Apps configuration..."

            BlankLine
            Section -Style Heading2 'Products and Components' {
                Paragraph "The following documents the Microsoft Defender for Cloud Apps (MDCA) solution components in scope for this tenant."
                BlankLine

                $ProductRows = @(
                    [pscustomobject]@{
                        'Product'    = 'Microsoft Defender for Cloud Apps'
                        'Components' = 'Cloud Application Discovery; Investigation; Policy'
                    },
                    [pscustomobject]@{
                        'Product'    = 'Microsoft 365'
                        'Components' = 'Exchange Online; SharePoint Online; OneDrive for Business; Power Automate; Power BI; Teams'
                    },
                    [pscustomobject]@{
                        'Product'    = 'Microsoft Azure'
                        'Components' = 'Microsoft Entra Auditing'
                    },
                    [pscustomobject]@{
                        'Product'    = 'Microsoft Security Center'
                        'Components' = 'Security Incident Portal'
                    }
                )

                $ProductParams = @{ Name = "MDCA Products in Scope - $TenantId"; ColumnWidths = 35, 65 }
                if ($Report.ShowTableCaptions) { $ProductParams['Caption'] = "- $($ProductParams.Name)" }
                $ProductRows | Table @ProductParams
            }

        } catch {
            Write-AbrSectionError -Section 'Defender for Cloud Apps Products' -Message "$($_.Exception.Message)"
        }

        # ── Data Sources ────────────────────────────────────────────────────────
        try {
            Write-Host " - Retrieving MDCA data sources..."

            # Try to fetch MCAS/MDCA settings via security Graph
            $McasSettingsResp = Invoke-MgGraphRequest -Method GET `
                -Uri "$($script:GraphEndpoint)/beta/security/cloudAppSecurityProfiles" `
                -ErrorAction SilentlyContinue

            BlankLine
            Section -Style Heading2 'Data Sources' {
                Paragraph "The following data sources provide activity logs and user/group data to Microsoft Defender for Cloud Apps."
                BlankLine

                $DataSourceRows = @(
                    [pscustomobject]@{
                        'Data Source' = 'Microsoft 365'
                        'Description' = 'Workload Activities — Exchange Online, SharePoint Online, OneDrive for Business, Dynamics 365, Power Automate, Power BI, Skype for Business, Teams, and Yammer'
                    },
                    [pscustomobject]@{
                        'Data Source' = 'Microsoft Entra'
                        'Description' = 'Users and Groups'
                    }
                )

                $DsParams = @{ Name = "MDCA Data Sources - $TenantId"; ColumnWidths = 25, 75 }
                if ($Report.ShowTableCaptions) { $DsParams['Caption'] = "- $($DsParams.Name)" }
                $DataSourceRows | Table @DsParams
            }

        } catch {
            if (Test-AbrGraphForbidden -ErrorRecord $_) {
                Write-AbrPermissionError -Section 'Defender for Cloud Apps Data Sources' -RequiredRole 'SecurityEvents.Read.All or Global Reader'
            } else { Write-AbrSectionError -Section 'Defender for Cloud Apps Data Sources' -Message "$($_.Exception.Message)" }
        }

        # ── Discovery Architecture ──────────────────────────────────────────────
        try {
            Write-Host " - Retrieving MDCA discovery configuration..."

            # Check MDE integration (continuous reporting feed via MDE telemetry)
            $MdeConnResp = Invoke-MgGraphRequest -Method GET `
                -Uri "$($script:GraphEndpoint)/beta/deviceManagement/mobileThreatDefenseConnectors" `
                -ErrorAction SilentlyContinue

            $MdeMcasIntegrated = $false
            if ($MdeConnResp.value) {
                $MdeMcasIntegrated = $MdeConnResp.value | Where-Object {
                    $_.partnerType -eq 'microsoftDefenderForEndpoint' -and $_.microsoftDefenderForEndpointEnabled -eq $true
                } | Select-Object -First 1
            }

            BlankLine
            Section -Style Heading2 'Discovery Architecture' {
                Paragraph "MDCA discovery facilitates ingestion of network logs from on-premises or cloud-based proxies and firewalls. The following documents the discovery mode configured for this tenant."
                BlankLine

                $DiscRows = [System.Collections.ArrayList]::new()

                $DiscRows.Add([pscustomobject]@{ 'Discovery Mode'  = 'Method'; 'Description' = 'Status / Notes' }) | Out-Null

                $mdeStatus = if ($MdeMcasIntegrated) { 'Enabled — Continuous Report feed active via MDE telemetry' } else { 'Not detected via Intune MDE connector' }
                $DiscRows = @(
                    [pscustomobject]@{
                        'Discovery Mode' = 'Microsoft Defender for Endpoint Integration'
                        'Description'    = $mdeStatus
                    },
                    [pscustomobject]@{
                        'Discovery Mode' = 'Continuous Reporting (Log Collector)'
                        'Description'    = 'Docker-based log collector accepts Syslog from firewalls/proxies for continuous feed'
                    },
                    [pscustomobject]@{
                        'Discovery Mode' = 'Manual Upload (Snapshot Report)'
                        'Description'    = 'Supports common firewall and proxy log formats; custom log formats also supported'
                    },
                    [pscustomobject]@{
                        'Discovery Mode' = 'REST API Upload'
                        'Description'    = 'Programmatic log file submission via MDCA API for parsing and analysis'
                    }
                )

                $null = ($DiscRows | Where-Object { $_.'Discovery Mode' -eq 'Microsoft Defender for Endpoint Integration' -and $MdeMcasIntegrated } | Set-Style -Style OK)

                $DiscParams = @{ Name = "MDCA Discovery Architecture - $TenantId"; ColumnWidths = 40, 60 }
                if ($Report.ShowTableCaptions) { $DiscParams['Caption'] = "- $($DiscParams.Name)" }
                $DiscRows | Table @DiscParams
            }

        } catch {
            if (Test-AbrGraphForbidden -ErrorRecord $_) {
                Write-AbrPermissionError -Section 'Defender for Cloud Apps Discovery' -RequiredRole 'SecurityEvents.Read.All'
            } else { Write-AbrSectionError -Section 'Defender for Cloud Apps Discovery' -Message "$($_.Exception.Message)" }
        }

        # ── API-Connected App Capabilities ──────────────────────────────────────
        try {
            Write-Host " - Retrieving MDCA connected app capabilities..."

            BlankLine
            Section -Style Heading2 'Files and Data Control' {
                Paragraph "MDCA uses API integration with Microsoft and third-party SaaS solutions to monitor and protect corporate files. The following natively supported SaaS solutions are available for API connection."
                BlankLine

                $SaasRows = @(
                    [pscustomobject]@{ 'SaaS Platform' = 'Microsoft 365';        'Capabilities' = 'User governance, DLP scan (periodic + near real-time), sharing control, file governance, app permissions, Azure Information Protection labels' },
                    [pscustomobject]@{ 'SaaS Platform' = 'Box';                   'Capabilities' = 'User governance, DLP scan (periodic + near real-time), sharing control, file governance' },
                    [pscustomobject]@{ 'SaaS Platform' = 'Dropbox';               'Capabilities' = 'User governance, DLP scan (periodic), sharing control, file governance' },
                    [pscustomobject]@{ 'SaaS Platform' = 'Google Workspace';      'Capabilities' = 'User governance, DLP scan (periodic + near real-time), sharing control, file governance, app permissions, revoke app permissions, Azure IP labels' },
                    [pscustomobject]@{ 'SaaS Platform' = 'Salesforce';            'Capabilities' = 'User governance, DLP scan (periodic), file governance, app permissions, revoke app permissions' },
                    [pscustomobject]@{ 'SaaS Platform' = 'ServiceNow';            'Capabilities' = 'User governance (partial), log on activity, administrative activity (partial)' },
                    [pscustomobject]@{ 'SaaS Platform' = 'AWS';                   'Capabilities' = 'Log on activity, user activity, administrative activity, sharing control, file governance' },
                    [pscustomobject]@{ 'SaaS Platform' = 'Okta';                  'Capabilities' = 'List accounts, log on activity, user activity, administrative activity' },
                    [pscustomobject]@{ 'SaaS Platform' = 'GitHub';                'Capabilities' = 'List accounts, log on activity, user activity, administrative activity, app permissions' },
                    [pscustomobject]@{ 'SaaS Platform' = 'Cisco Webex';           'Capabilities' = 'User governance, DLP scan (periodic), sharing control, log on activity, user activity, administrative activity' },
                    [pscustomobject]@{ 'SaaS Platform' = 'Workday';               'Capabilities' = 'List accounts (partial), administrative activity (partial)' }
                )

                $SaasParams = @{ Name = "MDCA Supported SaaS Platforms - $TenantId"; ColumnWidths = 25, 75 }
                if ($Report.ShowTableCaptions) { $SaasParams['Caption'] = "- $($SaasParams.Name)" }
                $SaasRows | Table @SaasParams
            }

        } catch {
            Write-AbrSectionError -Section 'Defender for Cloud Apps File and Data Control' -Message "$($_.Exception.Message)"
        }

        # ── Activity and Anomaly Detection ──────────────────────────────────────
        try {
            Write-Host " - Retrieving MDCA anomaly detection policies..."

            BlankLine
            Section -Style Heading2 'Activity and Anomaly Detection' {
                Paragraph "MDCA anomaly detection provides out-of-the-box user and entity behavioural analytics (UEBA) and machine learning (ML) for advanced threat detection. The following built-in threat detection scenarios are automatically active."
                BlankLine

                $AnomalyRows = @(
                    [pscustomobject]@{ 'Detection Scenario' = 'Malicious OAuth app consent';            'Category' = 'Application Threat' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Ransomware activity';                    'Category' = 'Ransomware' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Multiple failed login attempts';          'Category' = 'Account Compromise' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Unusual administrative activity (by user)';'Category' = 'Insider Threat' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Unusual file deletion activity (by user)';'Category' = 'Data Exfiltration' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Unusual file share activity (by user)';  'Category' = 'Data Exfiltration' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Activity from anonymous IP addresses';    'Category' = 'Account Compromise' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Impossible travel';                      'Category' = 'Account Compromise' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Unusual impersonated activity (by user)';'Category' = 'Insider Threat' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Multiple storage deletion activities';   'Category' = 'Data Destruction' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Activity performed by terminated user';  'Category' = 'Account Compromise' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Suspicious inbox manipulation rule';     'Category' = 'Email Threat' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Suspicious inbox forwarding';            'Category' = 'Email Threat' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Suspicious email deletion activity';     'Category' = 'Email Threat' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Activity from suspicious IP addresses';  'Category' = 'Account Compromise' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Suspicious OAuth app file download';     'Category' = 'Application Threat' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Malware detection';                      'Category' = 'Malware' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Unusual addition of credentials to OAuth app'; 'Category' = 'Application Threat' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Activity from infrequent country';       'Category' = 'Account Compromise' },
                    [pscustomobject]@{ 'Detection Scenario' = 'Leaked credentials';                     'Category' = 'Account Compromise' }
                )

                $AnomalyParams = @{ Name = "MDCA Built-in Threat Detections - $TenantId"; ColumnWidths = 70, 30 }
                if ($Report.ShowTableCaptions) { $AnomalyParams['Caption'] = "- $($AnomalyParams.Name)" }
                $AnomalyRows | Table @AnomalyParams
            }

        } catch {
            Write-AbrSectionError -Section 'Defender for Cloud Apps Anomaly Detection' -Message "$($_.Exception.Message)"
        }
    }

    end { Show-AbrDebugExecutionTime -End -TitleMessage 'Defender for Cloud Apps' }
}