Private/Comparison/New-ComparisonSummary.ps1

function New-ComparisonSummary {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [object]$Assignment,
        
        [Parameter()]
        [object]$PolicySet,
        
        [Parameter(Mandatory)]
        [object[]]$AssignedPolicies,
        
        [Parameter(Mandatory)]
        [object]$ComparisonResult,
        
        [Parameter()]
        [bool]$MatchByNameOnly = $false,
        
        [Parameter(Mandatory)]
        [object]$BaselineIndex
    )
    
    # Calculate InCommon count
    $inCommon = if ($MatchByNameOnly) {
        ($AssignedPolicies | Where-Object {
            $k = Normalize-PolicyName $_.PolicyDisplayName
            $k -and $BaselineIndex.ByNormName.ContainsKey($k)
        }).Count
    } else {
        ($AssignedPolicies | Where-Object {
            $BaselineIndex.ById.ContainsKey($_.PolicyDefinitionId)
        }).Count
    }
    
    # Detect if individual policy
    $isIndividualPolicy = $Assignment.PolicyDefinitionId -like "*/policyDefinitions/*" -and 
                          $Assignment.PolicyDefinitionId -notlike "*/policySetDefinitions/*"
    
    # Detect if this is MCSB
    $isMCSB = ($Assignment.DisplayName -ieq "Microsoft cloud security benchmark") -or 
              ($PolicySet.Id -like "*/1f3afdf9-d0c9-4c3d-847f-89da613e70a8")
    
    if (-not $isMCSB -and $isIndividualPolicy) {
        foreach ($policy in $AssignedPolicies) {
            $mcsbMatch = $BaselineIndex.ById[$policy.PolicyDefinitionId]
            if ($mcsbMatch -and $mcsbMatch.BaselineSources -like '*MCSB*') {
                $isMCSB = $true
                break
            }
        }
    }
    
    # Ensure AssignmentName is not empty
    $assignmentName = if (![string]::IsNullOrWhiteSpace($Assignment.Name)) {
        $Assignment.Name
    } elseif (![string]::IsNullOrWhiteSpace($Assignment.AssignmentName)) {
        $Assignment.AssignmentName
    } else {
        ($Assignment.DisplayName -replace '[\\/:*?"<>|]', '_') -replace '\s+', '-'
    }
    
    $totalPolicies = $AssignedPolicies.Count
    
    # ========== LOGIQUE CORRIGÉE ==========
    # Détecter si l'initiative/policy est custom (créée par l'utilisateur)
    $policyDefId = if ($PolicySet -and $PolicySet.Id) { 
        $PolicySet.Id 
    } elseif ($Assignment.PolicySetDefinitionId) {
        $Assignment.PolicySetDefinitionId
    } else { 
        $Assignment.PolicyDefinitionId 
    }
    
    $isCustomDefinition = $false
    if ($policyDefId) {
        # Custom = contient /subscriptions/ ou /managementGroups/ dans l'ID (pas built-in)
        $isCustomDefinition = ($policyDefId -match '/subscriptions/[^/]+/providers/Microsoft.Authorization/') -or
                              ($policyDefId -match '/providers/Microsoft.Management/managementGroups/[^/]+/providers/Microsoft.Authorization/')
    }
    
    # IsExtra = L'initiative/policy est custom (pas dans le catalogue Microsoft)
    $isExtra = $isCustomDefinition
    
    # Statut basé sur si c'est une définition custom ou non
    $assignmentStatus = if ($isCustomDefinition) {
        "Extra"    # Initiative/policy custom = toujours Extra
    } elseif ($inCommon -gt 0) {
        "Matched"  # Built-in avec policies dans le baseline
    } else {
        "Extra"    # Built-in mais aucune policy dans le baseline
    }
    
    # Fallback pour AssignmentDisplayName
    $displayName = if (![string]::IsNullOrWhiteSpace($Assignment.DisplayName)) {
        $Assignment.DisplayName
    } elseif (![string]::IsNullOrWhiteSpace($Assignment.AssignmentDisplayName)) {
        $Assignment.AssignmentDisplayName
    } else {
        $assignmentName
    }
    
    # Fallback pour InitiativeDefinitionId
    $initiativeId = if ($isIndividualPolicy) {
        "N/A (Individual Policy)"
    } elseif ($PolicySet -and ![string]::IsNullOrWhiteSpace($PolicySet.Id)) {
        $PolicySet.Id
    } elseif (![string]::IsNullOrWhiteSpace($Assignment.PolicyDefinitionId)) {
        $Assignment.PolicyDefinitionId
    } else {
        "-"
    }
    
    return [PSCustomObject]@{
        AssignmentDisplayName        = $displayName
        AssignmentName               = $assignmentName
        AssignmentScope              = $Assignment.Scope
        InitiativeDefinitionId       = $initiativeId
        TotalPolicies_Assignment     = $totalPolicies
        InCommon                     = $inCommon
        ExtraInAssignment_Count      = $ComparisonResult.Extra.Count
        VersionDiffs_Count           = $ComparisonResult.VersionDiffs.Count
        AssignmentStatus             = $assignmentStatus
        IsExtra                      = $isExtra
        IsMCSB                       = $isMCSB
        IsIndividualPolicy           = $isIndividualPolicy
    }
}