Checks/Azure/Test-KeyvaultPrivateEndpoint.ps1

function Test-KeyvaultPrivateEndpoint {
    <#
    .SYNOPSIS
        Tests that Azure Key Vaults have private endpoints configured.

    .DESCRIPTION
        Verifies that Key Vaults are configured with private endpoint connections.
        Private endpoints keep network traffic limited to whitelisted resources and
        prevent exposure of vault data over the public internet.

    .PARAMETER CheckMetadata
        Hashtable containing check metadata (id, service, title, severity).

    .OUTPUTS
        [CIEMScanResult[]] Array of scan result objects.
    #>

    [CmdletBinding()]
    [OutputType([CIEMScanResult[]])]
    param(
        [Parameter(Mandatory)]
        [hashtable]$CheckMetadata
    )

    $ErrorActionPreference = 'Stop'

    foreach ($subscriptionId in $script:KeyVaultService.Keys) {
        $kvData = $script:KeyVaultService[$subscriptionId]

        foreach ($vault in $kvData.KeyVaults) {
            # Strict mode safe property access
            $privateEndpoints = if ($vault.properties.PSObject.Properties['privateEndpointConnections']) {
                $vault.properties.privateEndpointConnections
            }
            else {
                $null
            }

            if ($privateEndpoints -and $privateEndpoints.Count -gt 0) {
                $approvedEndpoints = $privateEndpoints | Where-Object {
                    $_.properties.privateLinkServiceConnectionState.status -eq 'Approved'
                }

                if ($approvedEndpoints.Count -gt 0) {
                    $endpointNames = ($approvedEndpoints | ForEach-Object {
                        ($_.properties.privateEndpoint.id -split '/')[-1]
                    }) -join ', '

                    [CIEMScanResult]::Create($CheckMetadata, 'PASS', "Vault '$($vault.name)' has $($approvedEndpoints.Count) approved private endpoint(s): $endpointNames", $vault.id, $vault.name, $vault.location)
                }
                else {
                    [CIEMScanResult]::Create($CheckMetadata, 'FAIL', "Vault '$($vault.name)' has private endpoint connection(s) but none are in 'Approved' state.", $vault.id, $vault.name, $vault.location)
                }
            }
            else {
                [CIEMScanResult]::Create($CheckMetadata, 'FAIL', "Vault '$($vault.name)' does not have any private endpoints configured. Consider using private endpoints to secure network traffic.", $vault.id, $vault.name, $vault.location)
            }
        }
    }
}