Private/Azure/Test-PolicyAssigned.ps1

function Test-PolicyAssigned {
    <#
    .SYNOPSIS
        Check if a policy is assigned in the current scope.
     
    .DESCRIPTION
        Determines if a baseline policy is assigned by checking against indexed
        assignment collections. Supports matching by ID or normalized name.
     
    .PARAMETER PolicyDisplayName
        Display name of the policy to check.
     
    .PARAMETER PolicyDefinitionId
        Resource ID of the policy to check.
     
    .PARAMETER AssignedById
        Hashtable of assigned policies indexed by definition ID.
     
    .PARAMETER AssignedByNormName
        Hashtable of assigned policies indexed by normalized name.
     
    .PARAMETER MatchByNameOnly
        If true, match only by normalized name (ignore IDs).
     
    .EXAMPLE
        $isAssigned = Test-PolicyAssigned -PolicyDisplayName "Deploy VM Backup" -PolicyDefinitionId $id -AssignedById $byIdHash -AssignedByNormName $byNameHash -MatchByNameOnly $false
     
    .OUTPUTS
        Boolean - $true if policy is assigned, $false otherwise
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$PolicyDisplayName,
        
        [Parameter(Mandatory = $true)]
        [string]$PolicyDefinitionId,
        
        [Parameter(Mandatory = $true)]
        [hashtable]$AssignedById,
        
        [Parameter(Mandatory = $true)]
        [hashtable]$AssignedByNormName,
        
        [Parameter(Mandatory = $true)]
        [bool]$MatchByNameOnly
    )
    
    # Initialize counter if not exists
    if (-not $script:TestPolicyAssignedCallCount) {
        $script:TestPolicyAssignedCallCount = 0
    }
    
    # Debug first few calls
    $script:TestPolicyAssignedCallCount++
    if ($script:TestPolicyAssignedCallCount -le 3) {
        Write-Verbose "Test-PolicyAssigned call #$($script:TestPolicyAssignedCallCount): PolicyDisplayName=$PolicyDisplayName, PolicyDefinitionId=$PolicyDefinitionId, AssignedById.Count=$($AssignedById.Count), AssignedByNormName.Count=$($AssignedByNormName.Count)"
        
        # Show first few keys in hashtables for debugging
        if ($script:TestPolicyAssignedCallCount -eq 1) {
            $sampleKeys = $AssignedById.Keys | Select-Object -First 3
            Write-Verbose " Sample AssignedById keys: $($sampleKeys -join '; ')"
            $sampleNormKeys = $AssignedByNormName.Keys | Select-Object -First 3
            Write-Verbose " Sample AssignedByNormName keys: $($sampleNormKeys -join '; ')"
        }
    }
    
    if (-not $MatchByNameOnly) {
        # Try ID match first
        if ($AssignedById.ContainsKey($PolicyDefinitionId)) { 
            return $true 
        }
        
        # Fallback to normalized name match
        $normalizedName = Normalize-PolicyName $PolicyDisplayName
        if ($normalizedName -and $AssignedByNormName.ContainsKey($normalizedName)) { 
            return $true 
        }
        
        return $false
    } 
    else {
        # Name-only matching
        $normalizedName = Normalize-PolicyName $PolicyDisplayName
        if ($normalizedName -and $AssignedByNormName.ContainsKey($normalizedName)) { 
            return $true 
        }
        
        return $false
    }
}