Private/Show-NSPEntraAddressPlans.ps1

function Show-NSPEntraAddressPlans {
    [CmdletBinding()]
    param([Parameter(Mandatory)][AllowEmptyCollection()][object[]]$Plan)
    $blocked = @($Plan | Where-Object Blocked).Count
    Write-NSPConsoleRule -Title ('AD address preview: {0} total, {1} unblocked, {2} blocked' -f $Plan.Count,($Plan.Count-$blocked),$blocked)
    Write-NSPConsoleLine -Message 'Preview only. These plans have not been applied; unblocked does not establish hard-match readiness.' -Role Muted
    $text = {
        param($Value)
        if ($null -eq $Value -or [string]$Value -eq '') { return '(empty)' }
        [regex]::Replace([string]$Value, '[\x00-\x1F\x7F]', [Text.RegularExpressions.MatchEvaluator]{param($m) '\u{0:x4}' -f [int][char]$m.Value})
    }
    foreach ($item in $Plan) {
        $status = if ($item.Blocked) { 'BLOCKED' } else { 'UNBLOCKED' }
        $role = if ($item.Blocked) { 'Error' } else { 'Heading' }
        Write-NSPConsoleRule -Title ((& $text $item.Before.SamAccountName) + ' - ' + $status) -Role $role
        Write-NSPConsoleLine -Message (' AD GUID: {0} | Cloud ID: {1}' -f (& $text $item.ObjectGUID),(& $text $item.CloudBefore.ObjectId)) -Role Muted
        if ($item.Before.SamAccountName -cne $item.After.SamAccountName) {
            Write-NSPConsoleLine -Message (' Account name: {0} -> {1}' -f (& $text $item.Before.SamAccountName),(& $text $item.After.SamAccountName))
        }
        foreach ($reason in @($item.Reasons)) { if ($reason) { Write-NSPConsoleLine -Message (' BLOCK: ' + (& $text $reason)) -Role Error } }
        $sides = [ordered]@{'AD now'=$item.Before;'AD proposed'=$item.After;'Cloud current'=$item.CloudBefore}
        foreach ($label in $sides.Keys) {
            $side = $sides[$label]
            Write-NSPConsoleLine -Message (' ' + $label + ':') -Role Heading
            Write-NSPConsoleLine -Message (' UPN : ' + (& $text $side.UserPrincipalName))
            Write-NSPConsoleLine -Message (' Mail: ' + (& $text $side.Mail))
            $proxies = @($side.ProxyAddresses | Where-Object { $null -ne $_ })
            if (-not $proxies.Count) { Write-NSPConsoleLine -Message ' Proxies: (none)' }
            else {
                Write-NSPConsoleLine -Message ' Proxies:'
                foreach ($proxy in $proxies) {
                    $kind = if ([string]$proxy -cmatch '^SMTP:') { 'PRIMARY' } elseif ([string]$proxy -match '^smtp:') { 'alias' } else { 'other' }
                    Write-NSPConsoleLine -Message (' [{0}] {1}' -f $kind,(& $text $proxy))
                }
            }
        }
        if (@($item.ProxyAddressReview).Count) {
            Write-NSPConsoleLine -Message ' Cloud address preservation:' -Role Heading
            foreach ($proxy in @($item.ProxyAddressReview)) {
                $label = switch ($proxy.Disposition) {
                    'AddToAD' {'Proposed AD addition'} 'CloudManaged' {'Keep in cloud'} 'PresentInAD' {'Already in AD'}
                    'ExcludedByPolicy' {'Excluded by chosen policy'} 'NeedsReview' {'Review required'} default {[string]$proxy.Disposition}
                }
                Write-NSPConsoleLine -Message (' {0}: {1}' -f (& $text $label),(& $text $proxy.Address))
                if ($proxy.Reason) { Write-NSPConsoleLine -Message (' ' + (& $text $proxy.Reason)) -Role Muted }
            }
        }
    }
}