Private/Show-AACPolicyStateView.ps1

function Show-AACPolicyStateView {
    <#
    .SYNOPSIS
        Renders Get-AACPolicyState's result as a Spectre.Console view.
    .DESCRIPTION
        The scope, tiles (compliance, non-compliant and compliant resources,
        exempt, assignments, policies with non-compliant resources), then:
          Compliance by scope each subscription, and each resource group,
                               least compliant first
          Assignments least compliant first, with their scope and
                               enforcement
          Non-compliant each policy with non-compliant resources and
                               every one of them (up to -MaxResource), most
                               first
        Compliance: 90% or more green, 70-89% amber, below red. Wrap the call
        in Invoke-AACPagedOutput to page it.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [hashtable] $Compliance,

        [System.Collections.IDictionary] $Scope,

        [int] $MaxResource = 50
    )

    $escape = { param($Text) [Spectre.Console.Markup]::Escape([string]$Text) }
    $glyph = Get-AACGlyph
    $stats = $Compliance.Stats
    $rateColor = { param($Rate) if ($null -eq $Rate) { 'grey50' } elseif ($Rate -ge 90) { 'green3' } elseif ($Rate -ge 70) { 'orange1' } else { 'red1' } }
    $rate = { param($Rate) if ($null -eq $Rate) { '[grey50]-[/]' } else { "[bold $(& $rateColor $Rate)]$Rate%[/]" } }
    $count = { param([int] $Value, [string] $Color) if ($Value -eq 0) { '[grey42]0[/]' } else { "[$Color]$('{0:N0}' -f $Value)[/]" } }
    $newTable = {
        param([string] $Title, [string] $Color, [object[]] $Columns)
        $table = [Spectre.Console.Table]::new()
        $table.Border = [Spectre.Console.TableBorder]::Rounded
        $table.BorderStyle = [Spectre.Console.Style]::Parse($Color)
        $table.Expand = $true
        $table.Title = [Spectre.Console.TableTitle]::new($Title)
        foreach ($column in $Columns) {
            $spectre = [Spectre.Console.TableColumn]::new("[grey62]$($column[0])[/]")
            if ($column[1]) { $spectre.Alignment = [Spectre.Console.Justify]::Right; $spectre.NoWrap = $true }
            $table.AddColumn($spectre) | Out-Null
        }
        $table
    }
    $addRow = { param($Table, [string[]] $Cells) [Spectre.Console.TableExtensions]::AddRow($Table, [Spectre.Console.Rendering.IRenderable[]]@($Cells | ForEach-Object { [Spectre.Console.Markup]::new($_) })) | Out-Null }

    $facts = [System.Collections.Generic.List[string]]::new()
    if ($script:AACSession) { $facts.Add("[white]$(& $escape $script:AACSession.Account)[/]") }
    if ($Scope) { foreach ($key in $Scope.Keys) { $facts.Add("$(& $escape $key): $(& $escape $Scope[$key])") } }
    $facts.Add((Get-Date).ToString('d MMM yyyy HH:mm'))
    Write-AACMarkup "[grey58]$($facts -join " $($glyph.Dot) ")[/]"
    [Spectre.Console.AnsiConsole]::WriteLine()

    Show-AACTileRow -Tile @(
        @{ Value = $(if ($null -ne $stats.ComplianceRate) { "$($stats.ComplianceRate)%" } else { '-' }); Caption = ('resource compliance ({0:N0} of {1:N0})' -f $stats.CompliantCounted, $stats.Resources); Color = (& $rateColor $stats.ComplianceRate) }
        @{ Value = '{0:N0}' -f $stats.NonCompliant; Caption = 'non-compliant resources'; Color = $(if ($stats.NonCompliant) { 'red1' } else { 'green3' }) }
        @{ Value = '{0:N0}' -f $stats.Compliant; Caption = 'compliant resources'; Color = 'green3' }
        @{ Value = '{0:N0}' -f $stats.Exempt; Caption = 'exempt'; Color = 'grey70' }
        @{ Value = '{0:N0}' -f $stats.Assignments; Caption = 'assignments'; Color = 'mediumpurple2' }
        @{ Value = '{0:N0} / {1:N0}' -f $stats.NonCompliantInitiatives, $stats.Initiatives; Caption = 'non-compliant initiatives'; Color = $(if ($stats.NonCompliantInitiatives) { 'orange1' } else { 'green3' }) }
        @{ Value = '{0:N0} / {1:N0}' -f $stats.NonCompliantPolicies, $stats.Policies; Caption = 'non-compliant policies'; Color = $(if ($stats.NonCompliantPolicies) { 'orange1' } else { 'green3' }) }
    )
    [Spectre.Console.AnsiConsole]::WriteLine()
    foreach ($notice in @($Compliance.Notice | Where-Object { $_ })) { Write-AACMarkup "[deepskyblue1]i[/] [grey70]$(& $escape $notice)[/]" }
    if (@($Compliance.Notice).Count) { [Spectre.Console.AnsiConsole]::WriteLine() }
    if (-not $stats.States) { return }

    # --- By scope: subscriptions, then resource groups ----------------------------------------------------
    foreach ($level in 'Subscription', 'ResourceGroup') {
        $rows = @($Compliance.Scopes | Where-Object Level -EQ $level)
        if (-not $rows.Count) { continue }
        $title = if ($level -eq 'Subscription') { 'Compliance by subscription' } else { 'Compliance by resource group' }
        $columns = [System.Collections.Generic.List[object]]::new()
        $columns.Add(@($(if ($level -eq 'Subscription') { 'Subscription' } else { 'Resource group' }), $false))
        if ($level -eq 'ResourceGroup') { $columns.Add(@('Subscription', $false)) }
        foreach ($name in 'Compliance', 'Non-compliant', 'Compliant', 'Exempt', 'Resources') { $columns.Add(@($name, $true)) }
        $table = & $newTable "[bold]$($glyph.Bullet) $title[/] [grey58]$($glyph.Dot) least compliant first[/]" 'grey42' $columns.ToArray()
        foreach ($item in $rows) {
            & $addRow $table @(
                "[bold]$(& $escape $item.Name)[/]"
                if ($level -eq 'ResourceGroup') { "[grey70]$(& $escape $item.SubscriptionName)[/]" }
                (& $rate $item.ComplianceRate)
                (& $count $item.NonCompliant 'red1'); (& $count $item.Compliant 'green3'); (& $count $item.Exempt 'grey70'); (& $count $item.Resources 'grey85')
            )
        }
        [Spectre.Console.AnsiConsole]::Write($table)
        [Spectre.Console.AnsiConsole]::WriteLine()
    }

    # --- Assignments -----------------------------------------------------------------------------------------
    if ($Compliance.Assignments.Count) {
        $table = & $newTable "[bold mediumpurple2]$($glyph.Bullet) Assignments[/] [grey58]$($glyph.Dot) least compliant first[/]" 'mediumpurple2' @(@('Assignment', $false), @('Scope', $false), @('Compliance', $true), @('Non-compliant', $true), @('Compliant', $true), @('Policies failing', $true))
        foreach ($item in $Compliance.Assignments) {
            & $addRow $table @(
                "[bold]$(& $escape $item.Assignment)[/]$(if ($item.Enforcement -eq 'DoNotEnforce') { "`n[grey50](not enforced)[/]" })"
                "[grey70]$(& $escape $item.Scope)[/]"
                (& $rate $item.ComplianceRate)
                (& $count $item.NonCompliant 'red1'); (& $count $item.Compliant 'green3'); (& $count $item.NonCompliantPolicies 'orange1')
            )
        }
        [Spectre.Console.AnsiConsole]::Write($table)
        [Spectre.Console.AnsiConsole]::WriteLine()
    }

    # --- Non-compliant resources, by policy ----------------------------------------------------------------------
    $bad = @($Compliance.States | Where-Object ComplianceState -EQ 'NonCompliant' | Group-Object -Property Policy | Sort-Object -Property @{ Expression = 'Count'; Descending = $true }, Name)
    if ($bad.Count) {
        $table = & $newTable "[bold red1]$($glyph.Bullet) Non-compliant resources by policy[/] [grey58]$($glyph.Dot) $($stats.NonCompliant) resource(s)[/]" 'red3' @(@('Policy', $false), @('Resources', $true), @('Where', $false))
        foreach ($policy in $bad) {
            $first = $policy.Group[0]
            $what = "[bold]$(& $escape $policy.Name)[/]"
            $context = @($(if ($first.PolicySet) { "in $($first.PolicySet)" }), $first.Assignment, $(if ($first.Effect) { "effect: $($first.Effect)" })) | Where-Object { $_ }
            if ($context) { $what += "`n[grey58]$(& $escape ($context -join " $($glyph.Dot) "))[/]" }
            $shown = @($policy.Group | Select-Object -First $MaxResource)
            $where = @($shown | ForEach-Object { "[white]$(& $escape $_.Resource)[/] [grey50]$(& $escape (@($_.ResourceGroup, $_.SubscriptionName) | Where-Object { $_ }) -join ' / ')[/]" })
            if ($policy.Count -gt $shown.Count) { $where += "[grey50]... and $($policy.Count - $shown.Count) more: -PassThru, -CsvPath or -HtmlPath lists them all[/]" }
            & $addRow $table @($what, "[bold]$($policy.Count)[/]", ($where -join "`n"))
        }
        [Spectre.Console.AnsiConsole]::Write($table)
        [Spectre.Console.AnsiConsole]::WriteLine()
    }
    else {
        Show-AACPanel -Content '[bold green3]Every evaluated resource complies[/] [grey58]with every policy in this scope.[/]' -BorderColor 'green3' -AllowMarkup
        [Spectre.Console.AnsiConsole]::WriteLine()
    }
    Write-AACMarkup '[grey42]Compliance: (compliant + exempt + unknown + protected resources) / every resource evaluated, as the Azure portal counts it. Add -PassThru (or pipe the command) for every state; -CsvPath, -PdfPath or -HtmlPath for a report.[/]'
}