Private/Write-AACAssignedPolicyHtml.ps1
|
function Write-AACAssignedPolicyHtml { <# .SYNOPSIS Writes Get-AACAssignedPolicy's inventory as an interactive HTML report: tiles and charts that filter a table of the assignments and one of every parameter with its default, assigned and effective value. #> [CmdletBinding()] [OutputType([System.IO.FileInfo])] param( [Parameter(Mandatory)] [hashtable] $Inventory, [Parameter(Mandatory)] [string] $Path, [Parameter(Mandatory)] [string] $Title, [System.Collections.IDictionary] $Detail ) $stats = $Inventory.Stats $sourceTones = @{ Assigned = 'good'; Default = 'neutral'; 'Not set' = 'warn' } $enforcementTones = @{ Default = 'good'; DoNotEnforce = 'warn' } $kindTones = @{ Policy = 'info'; PolicySet = 'violet' } $scopeTones = @{ 'Management group' = 'violet'; Subscription = 'info'; 'Resource group' = 'good'; Resource = 'warn'; Other = 'neutral' } $tiles = @( @{ Value = '{0:N0}' -f $stats.Assignments; Label = 'assignments'; Tone = 'info'; Table = 'assignments' } @{ Value = '{0:N0}' -f $stats.Initiatives; Label = 'initiatives'; Tone = 'violet'; Table = 'assignments'; Filters = @{ DefinitionType = 'PolicySet' } } @{ Value = '{0:N0}' -f $stats.Policies; Label = 'single policies'; Tone = 'info'; Table = 'assignments'; Filters = @{ DefinitionType = 'Policy' } } @{ Value = '{0:N0}' -f $stats.Assigned; Label = 'parameters assigned'; Tone = 'good'; Table = 'parameters'; Filters = @{ ValueSource = 'Assigned' } } @{ Value = '{0:N0}' -f $stats.Default; Label = 'at their default'; Tone = 'neutral'; Table = 'parameters'; Filters = @{ ValueSource = 'Default' } } @{ Value = '{0:N0}' -f $stats.DoNotEnforce; Label = 'not enforced'; Tone = $(if ($stats.DoNotEnforce) { 'warn' } else { 'good' }); Table = 'assignments'; Filters = @{ EnforcementMode = 'DoNotEnforce' } } ) $charts = @( @{ Title = 'Assignments by scope'; Kind = 'donut'; CenterLabel = 'assignments'; Table = 'assignments'; Column = 'ScopeType'; Items = @($Inventory.Assignments | Group-Object ScopeType | ForEach-Object { @{ Label = $_.Name; Value = $_.Count; Tone = $scopeTones[$_.Name] } }) } @{ Title = 'Parameter values'; Kind = 'donut'; CenterLabel = 'parameters'; Table = 'parameters'; Column = 'ValueSource'; Items = @($Inventory.Rows | Where-Object ParameterName | Group-Object ValueSource | ForEach-Object { @{ Label = $_.Name; Value = $_.Count; Tone = $sourceTones[$_.Name] } }) } @{ Title = 'Resource types with the most assignments'; Wide = $true; Tone = 'info'; Items = @($stats.ResourceTypes | Select-Object -First 15 | ForEach-Object { @{ Label = $_.Label; Value = $_.Value } }) } ) $tables = @( @{ Id = 'assignments'; Title = 'Policy assignments'; Noun = 'assignments'; File = 'policy-assignments'; Rows = @($Inventory.Assignments); GroupBy = @('ScopeType', 'ScopeName', 'DefinitionType', 'Category') Columns = @( @{ Key = 'AssignmentDisplayName'; Label = 'Assignment' } @{ Key = 'ScopeType'; Label = 'Scope type'; Type = 'badge'; Tones = $scopeTones; Facet = $true } @{ Key = 'ScopeName'; Label = 'Assigned at'; Facet = $true } @{ Key = 'Inherited'; Label = 'Inherited'; Facet = $true } @{ Key = 'DefinitionDisplayName'; Label = 'Definition'; Type = 'wide' } @{ Key = 'DefinitionType'; Label = 'Type'; Type = 'badge'; Tones = $kindTones; Facet = $true } @{ Key = 'PolicyType'; Label = 'Built-in or custom'; Facet = $true } @{ Key = 'Category'; Label = 'Category'; Facet = $true } @{ Key = 'EnforcementMode'; Label = 'Enforcement'; Type = 'badge'; Tones = $enforcementTones; Facet = $true } @{ Key = 'Members'; Label = 'Policies'; Type = 'number'; Format = 'N0' } @{ Key = 'Parameters'; Label = 'Parameters'; Type = 'number'; Format = 'N0'; Sum = $true } @{ Key = 'Assigned'; Label = 'Assigned'; Type = 'number'; Format = 'N0'; Sum = $true } @{ Key = 'ResourceType'; Label = 'Resource types'; Type = 'wide' } @{ Key = 'NotScopes'; Label = 'Excluded scopes'; Type = 'wide'; Hidden = $true } @{ Key = 'AssignmentName'; Label = 'Name'; Type = 'mono'; Hidden = $true } @{ Key = 'AssignmentId'; Label = 'Assignment ID'; Type = 'mono'; Hidden = $true } @{ Key = 'DefinitionId'; Label = 'Definition ID'; Type = 'mono'; Hidden = $true } ) } @{ Id = 'parameters'; Title = 'Parameters'; Note = 'Effective: the assigned value, else the default. Resource types: what the policy (or, in an initiative, the policies using the parameter) applies to.'; Noun = 'parameters'; File = 'assigned-policy-parameters' Rows = @($Inventory.Rows); GroupBy = @('AssignmentDisplayName', 'ValueSource', 'ScopeName') Columns = @( @{ Key = 'AssignmentDisplayName'; Label = 'Assignment'; Facet = $true } @{ Key = 'ScopeName'; Label = 'Assigned at'; Facet = $true } @{ Key = 'DefinitionDisplayName'; Label = 'Definition'; Facet = $true; Hidden = $true } @{ Key = 'ParameterName'; Label = 'Parameter'; Type = 'mono' } @{ Key = 'ParameterDisplayName'; Label = 'Display name'; Hidden = $true } @{ Key = 'ParameterType'; Label = 'Type'; Facet = $true } @{ Key = 'ValueSource'; Label = 'Value from'; Type = 'badge'; Tones = $sourceTones; Facet = $true } @{ Key = 'EffectiveValue'; Label = 'Effective value'; Type = 'wide' } @{ Key = 'AssignedValue'; Label = 'Assigned'; Type = 'wide' } @{ Key = 'DefaultValue'; Label = 'Default'; Type = 'wide' } @{ Key = 'AllowedValues'; Label = 'Allowed values'; Type = 'wide'; Hidden = $true } @{ Key = 'ResourceType'; Label = 'Resource types'; Type = 'wide' } @{ Key = 'EnforcementMode'; Label = 'Enforcement'; Facet = $true; Hidden = $true } @{ Key = 'DefinitionType'; Label = 'Definition type'; Facet = $true; Hidden = $true } @{ Key = 'Category'; Label = 'Category'; Facet = $true; Hidden = $true } @{ Key = 'AssignmentName'; Label = 'Assignment name'; Type = 'mono'; Hidden = $true } ) } ) $notices = @(@($Inventory.Notice | Where-Object { $_ }) | ForEach-Object { @{ Tone = 'warn'; Text = $_ } }) $notices += @{ Tone = 'info'; Text = 'Read-only, from Azure Resource Graph (policyresources): the assignments, the definitions and initiatives they assign, and the initiatives'' member policies.' } Write-AACHtmlReport -Path $Path -Title $Title -Subtitle 'Every policy assignment, its parameters and the resource types it applies to' -Fact $Detail -Tile $tiles -Chart $charts -Table $tables -Notice $notices } |