Public/Get-ConditionalAccessReport.ps1
|
function Get-ConditionalAccessReport { <# .SYNOPSIS Exports Entra ID Conditional Access policies to CSV (and optionally raw JSON). .DESCRIPTION Requires Connect-MgGraph with Policy.Read.All. Read-only. Flattens the most useful conditions and controls into one row per policy. Use -IncludeJson to also save the full policy objects for backup or diffing. .PARAMETER IncludeJson Also write a JSON file with full policy definitions. .PARAMETER OutputFolder Folder for output. Defaults to ./output. .EXAMPLE Get-ConditionalAccessReport -IncludeJson #> [CmdletBinding()] param( [switch]$IncludeJson, [string]$OutputFolder = (Join-Path (Get-Location) 'output') ) $ErrorActionPreference = 'Stop' if (-not (Get-MgContext)) { throw 'Not connected. Run Connect-MgGraph first.' } New-Item -ItemType Directory -Path $OutputFolder -Force | Out-Null $stamp = Get-Date -Format 'yyyyMMdd-HHmm' $policies = Get-MgIdentityConditionalAccessPolicy -All $rows = $policies | ForEach-Object { $c = $_.Conditions [pscustomobject]@{ DisplayName = $_.DisplayName Id = $_.Id State = $_.State IncludeUsers = $c.Users.IncludeUsers -join ';' ExcludeUsers = $c.Users.ExcludeUsers -join ';' IncludeGroups = $c.Users.IncludeGroups -join ';' ExcludeGroups = $c.Users.ExcludeGroups -join ';' IncludeRoles = $c.Users.IncludeRoles -join ';' IncludeApps = $c.Applications.IncludeApplications -join ';' ExcludeApps = $c.Applications.ExcludeApplications -join ';' ClientAppTypes = $c.ClientAppTypes -join ';' Platforms = $c.Platforms.IncludePlatforms -join ';' IncludeLocations = $c.Locations.IncludeLocations -join ';' SignInRiskLevels = $c.SignInRiskLevels -join ';' UserRiskLevels = $c.UserRiskLevels -join ';' GrantOperator = $_.GrantControls.Operator GrantControls = $_.GrantControls.BuiltInControls -join ';' AuthStrength = $_.GrantControls.AuthenticationStrength.DisplayName SessionSignInFreq = $_.SessionControls.SignInFrequency.Value Modified = $_.ModifiedDateTime } } $file = Join-Path $OutputFolder "ConditionalAccess-$stamp.csv" $rows | Export-Csv -Path $file -NoTypeInformation if ($IncludeJson) { $policies | ConvertTo-Json -Depth 10 | Set-Content -Path (Join-Path $OutputFolder "ConditionalAccess-$stamp.json") } $byState = $rows | Group-Object State | ForEach-Object { "$($_.Name)=$($_.Count)" } Write-Information "Policies: $(@($rows).Count) ($($byState -join ', ')) -> $file" -InformationAction Continue } |