Public/ConditionalAccess.ps1
|
<# .SYNOPSIS Retrieves Conditional Access policies with optional filtering and summary metadata. .DESCRIPTION This function queries Conditional Access policies via Microsoft Graph and allows filtering by state. It returns both the raw policies and a lightweight summary view so you can quickly review state, app/user targets, and grant/session controls before making changes. .PARAMETER State Filter policies by state. Valid values: Enabled, Disabled, ReportOnly, All (default). .PARAMETER IncludeSummary If set, returns an additional Summary property for each policy with common fields. .EXAMPLE Get-O365ConditionalAccessPolicy -State ReportOnly -Verbose .EXAMPLE Get-O365ConditionalAccessPolicy -State Enabled -IncludeSummary | Format-Table -AutoSize .NOTES Requires Microsoft Graph permissions: Policy.Read.All at minimum. Source references: Office365itpros Conditional Access guidance; learn.microsoft.com/graph/api/conditionalaccessroot-list-policies. #> function Get-O365ConditionalAccessPolicy { [CmdletBinding()] param( [ValidateSet('Enabled','Disabled','ReportOnly','All')] [string]$State = 'All', [switch]$IncludeSummary ) $policies = Get-MgIdentityConditionalAccessPolicy -All if ($State -ne 'All') { $stateMap = @{ 'Enabled' = 'enabled' 'Disabled' = 'disabled' 'ReportOnly' = 'enabledForReportingButNotEnforced' } $targetState = $stateMap[$State] $policies = $policies | Where-Object { $_.State -eq $targetState } } if (-not $IncludeSummary) { return $policies } $policies | ForEach-Object { $summary = [PSCustomObject]@{ DisplayName = $_.DisplayName State = $_.State Id = $_.Id Users = $_.Conditions.Users | Select-Object -Property Users, IncludeUsers, ExcludeUsers, IncludeRoles, ExcludeRoles, IncludeGroups, ExcludeGroups, IncludeGuestsOrExternalUsers CloudApps = $_.Conditions.Applications | Select-Object -Property IncludeApplications, ExcludeApplications, IncludeUserActions Platforms = $_.Conditions.Platforms | Select-Object -Property IncludePlatforms, ExcludePlatforms GrantControls = $_.GrantControls | Select-Object -Property BuiltInControls, Operator, CustomAuthenticationFactors, TermsOfUse SessionControls = $_.SessionControls | Select-Object -Property ApplicationEnforcedRestrictions, CloudAppSecurity, PersistentBrowser, SignInFrequency } $_ | Add-Member -MemberType NoteProperty -Name "Summary" -Value $summary -PassThru } } <# .SYNOPSIS Changes the state of a Conditional Access policy (enable, disable, report-only). .DESCRIPTION This function updates a Conditional Access policy's state using Microsoft Graph. It defaults to SupportsShouldProcess to encourage WhatIf/Confirm use before modifying policies in production tenants. .PARAMETER PolicyId The Id of the Conditional Access policy to update. .PARAMETER State Target state. Valid values: Enabled, Disabled, ReportOnly. .EXAMPLE Set-O365ConditionalAccessPolicyState -PolicyId '1234-...' -State ReportOnly -WhatIf .EXAMPLE Set-O365ConditionalAccessPolicyState -PolicyId '1234-...' -State Enabled -Confirm .NOTES Requires Microsoft Graph permissions: Policy.ReadWrite.ConditionalAccess. Source references: Office365itpros Conditional Access change controls; learn.microsoft.com/graph/api/conditionalaccesspolicy-update. #> function Set-O365ConditionalAccessPolicyState { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory=$true)] [string]$PolicyId, [Parameter(Mandatory=$true)] [ValidateSet('Enabled','Disabled','ReportOnly')] [string]$State ) $stateMap = @{ 'Enabled' = 'enabled' 'Disabled' = 'disabled' 'ReportOnly' = 'enabledForReportingButNotEnforced' } $targetState = $stateMap[$State] $policy = Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $PolicyId if (-not $policy) { Write-Warning "Conditional Access policy not found: $PolicyId" return } if ($PSCmdlet.ShouldProcess($policy.DisplayName, "Set Conditional Access policy state to $State")) { Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $PolicyId -BodyParameter @{state = $targetState} | Out-Null return Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $PolicyId } } <# .SYNOPSIS Clones a Conditional Access policy into a new policy. .DESCRIPTION This function copies a source Conditional Access policy (conditions, assignments, grant/session controls) into a new policy with a specified display name and desired state. It defaults the new policy to Disabled to avoid accidental impact. .PARAMETER SourcePolicyId The Id of the existing Conditional Access policy to clone. .PARAMETER TargetDisplayName The display name for the new policy. .PARAMETER TargetState The desired state for the cloned policy. Defaults to Disabled. .EXAMPLE Copy-O365ConditionalAccessPolicy -SourcePolicyId 'abcd-...' -TargetDisplayName 'CA - Test clone' -TargetState Disabled .EXAMPLE Copy-O365ConditionalAccessPolicy -SourcePolicyId 'abcd-...' -TargetDisplayName 'CA - Report-only clone' -TargetState ReportOnly -WhatIf .NOTES Requires Microsoft Graph permissions: Policy.Read.All and Policy.ReadWrite.ConditionalAccess. Source references: Office365itpros policy hygiene guidance; learn.microsoft.com/graph/api/conditionalaccessroot-post-policies. #> function Copy-O365ConditionalAccessPolicy { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory=$true)] [string]$SourcePolicyId, [Parameter(Mandatory=$true)] [string]$TargetDisplayName, [ValidateSet('Enabled','Disabled','ReportOnly')] [string]$TargetState = 'Disabled' ) $stateMap = @{ 'Enabled' = 'enabled' 'Disabled' = 'disabled' 'ReportOnly' = 'enabledForReportingButNotEnforced' } $policy = Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $SourcePolicyId if (-not $policy) { Write-Warning "Conditional Access policy not found: $SourcePolicyId" return } $body = @{ displayName = $TargetDisplayName state = $stateMap[$TargetState] conditions = $policy.Conditions grantControls = $policy.GrantControls sessionControls = $policy.SessionControls description = $policy.Description } if ($PSCmdlet.ShouldProcess($TargetDisplayName, "Create clone of Conditional Access policy '$($policy.DisplayName)'")) { $newPolicy = New-MgIdentityConditionalAccessPolicy -BodyParameter $body return $newPolicy } } <# .SYNOPSIS Exports Conditional Access policies to JSON for backup or templating. .DESCRIPTION This function exports one or more Conditional Access policies to a JSON file. It can export all policies or a specific policy by Id. .PARAMETER OutputPath Destination file path for the JSON export. .PARAMETER PolicyId Optional Id of a single policy to export. If omitted, all policies are exported. .EXAMPLE Export-O365ConditionalAccessPolicy -OutputPath '.\\ca-policies-backup.json' .EXAMPLE Export-O365ConditionalAccessPolicy -PolicyId 'abcd-...' -OutputPath '.\\ca-policy.json' .NOTES Requires Microsoft Graph permissions: Policy.Read.All. Source references: Office365itpros backup guidance; learn.microsoft.com/graph/api/conditionalaccesspolicy-get. #> function Export-O365ConditionalAccessPolicy { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string]$OutputPath, [string]$PolicyId ) $policies = if ($PolicyId) { @(Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $PolicyId) } else { Get-MgIdentityConditionalAccessPolicy -All } if (-not $policies) { Write-Warning "No Conditional Access policies found to export." return } $json = $policies | ConvertTo-Json -Depth 15 $OutputDirectory = Split-Path -Path $OutputPath -Parent if ($OutputDirectory -and -not (Test-Path -Path $OutputDirectory)) { New-Item -ItemType Directory -Path $OutputDirectory | Out-Null } $json | Out-File -FilePath $OutputPath -Encoding utf8 Write-Verbose "Exported $($policies.Count) Conditional Access policy(ies) to $OutputPath" } <# .SYNOPSIS Imports Conditional Access policies from JSON. .DESCRIPTION This function reads a JSON file containing one or more Conditional Access policy definitions (such as those produced by Export-O365ConditionalAccessPolicy) and creates new policies. By default, imported policies are created Disabled to reduce risk; you can override with TargetState. .PARAMETER Path Path to the JSON file containing policy definitions. .PARAMETER TargetState State to apply to imported policies. Defaults to Disabled. .EXAMPLE Import-O365ConditionalAccessPolicy -Path '.\\ca-policies-backup.json' -TargetState Disabled -WhatIf .EXAMPLE Import-O365ConditionalAccessPolicy -Path '.\\ca-policy.json' -TargetState ReportOnly .NOTES Requires Microsoft Graph permissions: Policy.ReadWrite.ConditionalAccess. Source references: Office365itpros deployment checklists; learn.microsoft.com/graph/api/conditionalaccessroot-post-policies. #> function Import-O365ConditionalAccessPolicy { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory=$true)] [string]$Path, [ValidateSet('Enabled','Disabled','ReportOnly')] [string]$TargetState = 'Disabled' ) if (-not (Test-Path -Path $Path)) { Write-Warning "File not found: $Path" return } $stateMap = @{ 'Enabled' = 'enabled' 'Disabled' = 'disabled' 'ReportOnly' = 'enabledForReportingButNotEnforced' } $content = Get-Content -Path $Path -Raw | ConvertFrom-Json $policies = if ($content -is [System.Collections.IEnumerable]) { $content } else { @($content) } $created = @() foreach ($policy in $policies) { $body = @{ displayName = $policy.displayName description = $policy.description state = $stateMap[$TargetState] conditions = $policy.conditions grantControls = $policy.grantControls sessionControls = $policy.sessionControls } if ($PSCmdlet.ShouldProcess($policy.displayName, "Import Conditional Access policy as $TargetState")) { $newPolicy = New-MgIdentityConditionalAccessPolicy -BodyParameter $body $created += $newPolicy } } return $created } |