Private/Comparison/Find-ExtraPolicies.ps1

function Find-ExtraPolicies {
    <#
    .SYNOPSIS
    Finds assigned policies that are not in the baseline.
     
    .DESCRIPTION
    Compares assigned policies against the baseline to identify
    which policies are deployed but not part of the baseline (extras).
    Supports both ID-based and name-based matching strategies.
     
    .PARAMETER AssignedPolicies
    Array of assigned policy objects with PolicyDefinitionId and PolicyDisplayName.
     
    .PARAMETER BaselineIndex
    Hashtable for fast lookup of baseline policies (ById or ByNormName).
     
    .PARAMETER MatchByNameOnly
    If true, matches by normalized name only. If false, matches by ID first, then name.
     
    .EXAMPLE
    $extra = Find-ExtraPolicies -AssignedPolicies $assRefs `
                                 -BaselineIndex $baselineIndexByNorm `
                                 -MatchByNameOnly $true
     
    Returns array of assigned policies not found in baseline.
     
    .OUTPUTS
    Array of PSCustomObject assigned policies that are not in the baseline.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [object[]]$AssignedPolicies,
        
        [Parameter(Mandatory)]
        [hashtable]$BaselineIndex,
        
        [Parameter()]
        [bool]$MatchByNameOnly = $false
    )
    
    $extra = foreach ($r in $AssignedPolicies) {
        if ($MatchByNameOnly) {
            # Match by normalized name only
            $k = Normalize-PolicyName $r.PolicyDisplayName
            if (-not $k) { continue }
            if (-not $BaselineIndex.ContainsKey($k)) { $r }
        }
        else {
            # Match by ID first, fallback to name
            if (-not $BaselineIndex.ContainsKey($r.PolicyDefinitionId)) {
                $k = Normalize-PolicyName $r.PolicyDisplayName
                if ($k -and -not $BaselineIndex.ContainsKey($k)) { $r }
                elseif (-not $k) { $r }
            }
        }
    }
    
    return $extra
}