tests/Test-Assessment.35039.ps1

<#
.SYNOPSIS
    Validates that Communication Compliance rules are configured to detect and monitor Copilot content.
 
.DESCRIPTION
    This test verifies that Communication Compliance rules targeting Copilot interactions are properly
    configured and enabled. It checks that supervisory review policies with Copilot-targeting rules
    are active and have configured review mailboxes for processing alerts.
 
.NOTES
    Test ID: 35039
    Category: Data Security Posture Management
    Pillar: Data
    Required Module: ExchangeOnlineManagement
    Required Connection: Security & Compliance PowerShell
#>


function Test-Assessment-35039 {
    [ZtTest(
        Category = 'Data Security Posture Management',
        ImplementationCost = 'Medium',
        MinimumLicense = ('Microsoft 365 E5'),
        Pillar = 'Data',
        RiskLevel = 'High',
        SfiPillar = 'Protect tenants and production systems',
        TenantType = ('Workforce'),
        TestId = 35039,
        Title = 'Copilot Communication Compliance Monitoring Configured',
        UserImpact = 'Medium'
    )]
    [CmdletBinding()]
    param()

    #region Data Collection
    Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose

    $activity = 'Checking Communication Compliance Rules for Copilot Content'
    Write-ZtProgress -Activity $activity -Status 'Getting supervisory review rules'

    # Q1: Find Communication Compliance rules targeting Copilot content
    $copilotRules = @()
    $errorMsg = $null

    try {
        $allRules = Get-SupervisoryReviewRule -IncludeRuleXml -ErrorAction Stop
        $allReviewPolicy = Get-SupervisoryReviewPolicyV2

        foreach ($rule in $allRules) {
            if (-not [string]::IsNullOrWhiteSpace($rule.RuleXml)) {
                try {
                    # Wrap RuleXml in a root element to handle multiple rule elements
                    $wrappedXml = "<root>$($rule.RuleXml)</root>"
                    $ruleXml = [xml]$wrappedXml
                    $hasCopilotConfig = $false

                    # Check for Copilot in Workloads array within JSON value elements
                    if ($ruleXml.root) {
                        $valueElements = $ruleXml.root.GetElementsByTagName('value')
                        foreach ($valueElement in $valueElements) {
                            if (-not [string]::IsNullOrWhiteSpace($valueElement.'#text')) {
                                try {
                                    $jsonData = $valueElement.'#text' | ConvertFrom-Json
                                    if ($jsonData.Workloads -and $jsonData.Workloads -contains 'Copilot') {
                                        $hasCopilotConfig = $true
                                        break
                                    }
                                }
                                catch {
                                    # Skip if JSON parsing fails
                                }
                            }
                        }
                    }

                    if ($hasCopilotConfig) {
                        # Lookup policy name from $allReviewPolicy using Policy ID
                        $policyId = $rule.Policy
                        $policyName = ($allReviewPolicy | Where-Object { $_.Guid -eq $policyId }).Name

                        $copilotRules += [PSCustomObject]@{
                            RuleName   = $rule.Name
                            PolicyId   = $policyId
                            PolicyName = if ($policyName) { $policyName } else { 'Unknown' }
                        }
                    }
                }
                catch {
                    Write-PSFMessage "Error parsing RuleXml for rule '$($rule.Name)': $_" -Level Warning
                }
            }

        }
    }
    catch {
        $errorMsg = $_
        Write-PSFMessage "Failed to retrieve supervisory review rules: $_" -Tag Test -Level Warning
    }

    # Q2: Resolve Copilot-targeting policies and verify enabled status
    $enabledCopilotPolicies = @()
    if ($copilotRules -and -not $errorMsg) {
        #Write-ZtProgress -Activity $activity -Status 'Verifying policy enabled status'

        try {
            $copilotPolicyIdentities = @($copilotRules | Select-Object -ExpandProperty PolicyId -Unique)
            $policies = foreach ($id in $copilotPolicyIdentities) {
                $allReviewPolicy | Where-Object { $_.Guid -eq $id }
            }
            $enabledCopilotPolicies = @($policies | Where-Object { $_ -and $_.Enabled -eq $true })
        }
        catch {
            Write-PSFMessage "Failed to retrieve supervisory review policies: $_" -Tag Test -Level Warning
        }
    }

    # Q3: Verify Copilot capture is active by checking audit logs (optional)
    $policyHits = $null
    if ($enabledCopilotPolicies) {
        Write-ZtProgress -Activity $activity -Status 'Checking audit logs'

        try {
            $startDate = (Get-Date).AddDays(-30)
            $endDate = Get-Date
            $hits = Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate -Operations SupervisionRuleMatch -ErrorAction Stop

            if ($hits) {
                $policyNamePattern = ($enabledCopilotPolicies.Name | ForEach-Object { [regex]::Escape($_) }) -join '|'
                $policyHits = @($hits | Where-Object { $_.AuditData -match $policyNamePattern -and ($_.AuditData -match 'Copilot') })
            }
        }
        catch {
            Write-PSFMessage "Failed to check audit logs: $_" -Tag Test -Level Warning
        }
    }
    #endregion Data Collection

    #region Assessment Logic
    $passed = $false

    # Evaluation Logic:
    # 1. If Query 1 returns at least 1 rule with Copilot in RuleXml, proceed to Query 2
    if ($copilotRules.Count -gt 0) {
        # 2. If Query 2 returns at least 1 enabled policy with ReviewMailbox configured, then Pass
        $hasValidPolicies = @($enabledCopilotPolicies | Where-Object { $_.ReviewMailbox }).Count -gt 0
        $passed = $hasValidPolicies
    }
    # 3. If Query 1 returns no rules or Query 2 returns no enabled policies, then Fail
    else {
        $passed = $false
    }
    # Query 3 (audit logs) is optional and used only for evidence display
    #endregion Assessment Logic

    #region Report Generation
    $mdInfo = ''

    if ($passed) {
        $statusIcon = '✅ Pass'
        $statusMessage = 'Communication Compliance rules targeting Copilot content are properly configured and enabled.'
    }
    else {
        $statusIcon = '❌ Fail'
        $statusMessage = 'Communication Compliance rules targeting Copilot content are not properly configured or enabled.'
    }

    # Copilot-Targeting Rules section
    if ($copilotRules -and $copilotRules.Count -gt 0) {
        $rulesTableRows = ''
        foreach ($rule in $copilotRules | Sort-Object RuleName) {
            $rulesTableRows += "| $($rule.RuleName) | $($rule.PolicyName) |`n"
        }

        $rulesTemplate = @'
 
### Copilot-Targeting Rules
 
| Rule Name | Associated Policy |
| :------ | :---- |
{0}
'@

        $mdInfo += $rulesTemplate -f $rulesTableRows
    }
    else {
        $mdInfo += "`n### Copilot-Targeting Rules`n`nNo Copilot-targeting rules found.`n"
    }

    # Enabled Policies section
    if ($enabledCopilotPolicies -and $enabledCopilotPolicies.Count -gt 0) {
        $policiesTableRows = ''
        foreach ($policy in $enabledCopilotPolicies | Sort-Object Name) {
            $reviewMailbox = if ($policy.ReviewMailbox) { $policy.ReviewMailbox } else { 'Not configured' }
            $enabledStatus = if ($policy.Enabled -eq $true) { 'True' } else { 'False' }
            $policiesTableRows += "| $($policy.Name) | $enabledStatus | $reviewMailbox |`n"
        }

        $policiesTemplate = @'
 
### Enabled Policies
 
| Policy Name | Enabled | Review Mailbox |
| :------ | :---- | :---- |
{0}
'@

        $mdInfo += $policiesTemplate -f $policiesTableRows
    }
    else {
        $mdInfo += "`n### Enabled Policies`n`nNo enabled policies with Copilot rules found.`n"
    }

    # Activity Evidence section
    $evidenceText = if ($policyHits -and $policyHits.Count -gt 0) {
        "Recent Copilot Matches (30 days): $($policyHits.Count)"
    }
    elseif ($enabledCopilotPolicies -and $enabledCopilotPolicies.Count -gt 0) {
        "Recent Copilot Matches (30 days): 0"
    }
    else {
        "Recent Copilot Matches (30 days): No policies configured for audit review."
    }

    $mdInfo += "`n### Activity Evidence`n`n$evidenceText`n"

    # Summary
    $summaryTemplate = @'
 
**Summary:**
 
 Status: {0}
 
 Total Copilot Rules Found: {1}
 
 Enabled Policies with Copilot Rules: {2}
 
**Portal Access:**
 
 [Microsoft Purview Communication Compliance > Policies](https://purview.microsoft.com/communicationcompliance/policies)
 
'@


    $mdInfo += $summaryTemplate -f $statusIcon, $copilotRules.Count, $enabledCopilotPolicies.Count

    $testResultMarkdown = "$statusMessage`n$mdInfo"

    #endregion Report Generation

    $params = @{
        TestId = '35039'
        Status = $passed
        Result = $testResultMarkdown
    }

    Add-ZtTestResultDetail @params
}