Public/Compare-AzRoleAccessGuardExport.ps1
|
function Compare-AzRoleAccessGuardExport { <# .SYNOPSIS Compares a full role assignment export against a baseline export file and reports the differences, without querying Azure. #> [CmdletBinding()] param( # Full export file (e.g. produced by Export-AzRoleAccessGuard -IncludeInherited) treated as the current/actual state. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$FullExportFile, # Baseline export file (e.g. produced by Export-AzRoleAccessGuard) treated as the reference/desired state. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$ExportFile, # Where the detected differences are written, without extension; the correct extension is appended based on -OutputFormat. [string]$OutputPath = (Join-Path (Split-Path -Parent $PSScriptRoot) 'output_export_diff'), # Output format for the comparison report. 'Terminal' prints a table to the host instead of writing a file. Defaults to Json. [ValidateSet('Terminal', 'Json', 'Html', 'Csv', 'JUnit')] [string]$OutputFormat = 'Json' ) if (-not (Test-Path -LiteralPath $FullExportFile -PathType Leaf)) { throw "Full export file '$FullExportFile' was not found." } if (-not (Test-Path -LiteralPath $ExportFile -PathType Leaf)) { throw "Export file '$ExportFile' was not found." } $full_export = Get-Content -LiteralPath $FullExportFile -Raw | ConvertFrom-Json $full_export = ConvertFrom-RoleAssignmentExportDocument -ExportData $full_export $export = Get-Content -LiteralPath $ExportFile -Raw | ConvertFrom-Json $export = ConvertFrom-RoleAssignmentExportDocument -ExportData $export $drift_result = [ordered]@{ ManagementGroup = [ordered]@{} Subscription = [ordered]@{} } $scope_test_results = @() foreach ($section in 'ManagementGroup', 'Subscription') { $current_section = $full_export.$section $reference_section = $export.$section $current_ids = @() if ($current_section) { $current_ids = @($current_section.PSObject.Properties.Name) } $reference_ids = @() if ($reference_section) { $reference_ids = @($reference_section.PSObject.Properties.Name) } $all_ids = @($current_ids + $reference_ids) | Select-Object -Unique foreach ($id in $all_ids) { $current_assignments = @() if ($current_ids -contains $id) { $current_assignments = @($current_section.$id) } $reference_assignments = @() if ($reference_ids -contains $id) { $reference_assignments = @($reference_section.$id) } $id_diff = Compare-AzRoleAssignmentSet -ReferenceAssignments $reference_assignments -CurrentAssignments $current_assignments $scope_test_results += [PSCustomObject]@{ Section = $section ScopeId = $id Diff = $id_diff } if ($id_diff.Count -gt 0) { $drift_result[$section][$id] = $id_diff } } } $drift_output = [PSCustomObject]@{ ManagementGroup = [PSCustomObject]$drift_result.ManagementGroup Subscription = [PSCustomObject]$drift_result.Subscription } $drift_documents = ConvertTo-RoleAssignmentDriftDocuments -DriftResult $drift_result -Description 'Role assignment drift detected between the full export and the export file.' switch ($OutputFormat) { 'Terminal' { New-FlatDriftResultList -DriftResult $drift_result | Format-Table -AutoSize } 'Json' { $drift_documents | ConvertTo-Json -Depth 6 | Out-File -FilePath "$OutputPath.json" -Encoding utf8 Write-Host "Comparison report written to $OutputPath.json" } 'Html' { ConvertTo-DriftGroupedHtmlReport -Title 'Azure Role Assignment Export Comparison' -DriftResult $drift_result -GeneratedBy 'Compare-AzRoleAccessGuardExport' | Out-File -FilePath "$OutputPath.html" -Encoding utf8 Write-Host "Comparison report written to $OutputPath.html" } 'Csv' { New-FlatDriftResultList -DriftResult $drift_result | Export-Csv -Path "$OutputPath.csv" -NoTypeInformation -Encoding utf8 Write-Host "Comparison report written to $OutputPath.csv" } 'JUnit' { ConvertTo-DriftJUnitXml -ScopeResults $scope_test_results -SuiteName 'AzRoleAssignmentExportComparison' | Out-File -FilePath "$OutputPath.xml" -Encoding utf8 Write-Host "Comparison report written to $OutputPath.xml" } } $total_changes = ($drift_result.ManagementGroup.Values + $drift_result.Subscription.Values | ForEach-Object { $_.Count } | Measure-Object -Sum).Sum Write-Host "Comparison complete. $total_changes change(s) found between full export and export." return $drift_output } |