Azure AD Conditional Access Maintenance and Automation Task - chadmcox/Azure_Active_Directory GitHub Wiki
Add Break Glass to All Conditional Access Policies
Conditional Access Backup and Restore Procedure
Objective:
- Backup and restore Conditional Access Policies in Azure AD
- Backup and restore Conditional Access Named Location in Azure AD
Notes:
These two cmdlets are junk "New-MgIdentityConditionalAccessPolicy" and "New-MgIdentityConditionalAccessPolicy"
Backup Policies
Using PowerShell
- This will require the Microsoft.Graph.Authentication modules
#check to see if module installed
PS C:\> get-module Microsoft.Graph.Authentication -listavailable
#if not installed, then install it
PS C:\> install-module Microsoft.Graph.Authentication
#or install all the microsoft.graph modules
PS C:\> install-module Microsoft.Graph
- Sign-in to the tenant with an account with Global Admins, Conditional Access Admins, or Security Admins
- Will also need to provide the permissions and consent
PS C:\> Connect-MgGraph -Scopes "Policy.Read.All", "Policy.ReadWrite.ConditionalAccess", "Directory.ReadWrite.All", "Directory.AccessAsUser.All"
- Create a folder to store the backups
# Create folder
PS C:\> new-item c:\backup -type directory
PS C:\> new-item 'c:\backup\conditional access policies' -type directory
- Backup the policies
# Export Conditional Access policies from graph to variable named caps
PS C:\> Invoke-MgGraphRequest -Method GET -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies" -OutputType PSObject | select -ExpandProperty value -OutVariable caps
# Write the conditional access policies to files
PS C:\> $caps | foreach {$cap = $_;$cap | convertto-json -Depth 99 | out-file "c:\backup\conditional access policies\$(Get-Date -Format "yyyy_MM_dd") $($cap.displayname -replace("/"," ")).json"}
- Should look something like this in the folder
PS C:\> dir 'c:\backup\conditional access policies' | select name
Name
----
2022_04_06 All Users - Block Legacy Authentication.json
2022_04_06 All Users - Block Tor Exit Nodes.json
2022_04_06 All Users - Require Compliant Device for All Cloud Apps.json
2022_04_06 All Users - Require MFA Device Join Registration.json
2022_04_06 All Users - Require MFA for All Cloud Apps.json
Restore Policies
Using PowerShell
- Sign-in to the tenant with an account with Global Admins, Conditional Access Admins, or Security Admins
- Will also need to provide the permissions and consent
PS C:\> Connect-MgGraph -Scopes "Policy.Read.All", "Policy.ReadWrite.ConditionalAccess", "Directory.ReadWrite.All", "Directory.AccessAsUser.All"
- Read the file and import the policy
# Read the json and store in a variable as an object
PS C:\> get-content 'c:\backup\conditional access policies\2022_04_06 All Users - Block Legacy Authentication.json' | convertfrom-json | select displayName, state, sessionControls, conditions, grantControls -OutVariable restorePolicy
# Using graph import the contents of the json
PS C:\> Invoke-MgGraphRequest -Method POST -uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" `
-ContentType "application/json" -Body ($restorePolicy | convertto-json -Depth 99)
Backup Named Locations
- Create a folder to store the backups
# Create folder
PS C:\> new-item c:\backup -type directory
PS C:\> new-item 'c:\backup\named locations' -type directory
- Backup the named locations
# Export Conditional Access policies from graph to variable named caps
PS C:\> Invoke-MgGraphRequest -Method GET -uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" -OutputType PSObject | select -ExpandProperty value -OutVariable caps
# Write the conditional access policies to files
PS C:\> $caps | foreach {$cap = $_;$cap | convertto-json -Depth 99 | out-file "c:\backup\named locations\$(Get-Date -Format "yyyy_MM_dd") $($cap.displayname -replace("/"," ")).json"}
- Should look something like this in the folder
PS C:\> dir 'c:\backup\named locations' | select name
Name
----
2022_04_06 Office 1.json
2022_04_06 Tor Exit Nodes.json
2022_04_06 Office 2.json
2022_04_06 Office 3.json
2022_04_06 Office 4.json
Restore Named Locations
# Read the file and store to variable
get-content 'c:\backup\named locations\2022_04_06 Tor Exit Nodes.json' | convertfrom-json | select "@odata.type",displayName,isTrusted,ipRanges -OutVariable restoreNameLocation
# import named location
Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations" -Body ($restoreNameLocation | convertto-json -Depth 99)
Automate Exclusion of BreakGlass / Emergency Access Account.
This link will take you to script that does this
Automate Exclusion Group Creation for Conditional Access Policies.
Using PowerShell
Connect-MgGraph -Scopes "Policy.Read.All", "Policy.ReadWrite.ConditionalAccess", "Directory.ReadWrite.All", "Directory.AccessAsUser.All", "GroupMember.ReadWrite.All","Group.ReadWrite.All"
#update this to meet requirements
$groupprefix = "GRP.CAP.Exclude"
#Create Admin Unit
$body = @"
{
"displayName": "AU.CAP.Exclusion - Conditional Access Policy Exclusion Groups",
"description": "Conditional Access Policy Exclusion Groups for administration",
"visibility": "HiddenMembership"
}
"@
$au = Invoke-MgGraphRequest -Method POST -uri "https://graph.microsoft.com/beta/administrativeUnits" -ContentType 'application/json' -body $body
$AllPolicies = (Invoke-MgGraphRequest -Method GET -uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" -OutputType PSObject).value
#Create groups for each policy, link to admin unit and update cap
#will need to run rest of this code together.
foreach($p in $AllPolicies){
$body = @"
{
"@odata.type": "#Microsoft.Graph.Group",
"description": "Group to Exclude Conditional Access Policy: $($p.displayname)",
"displayName": "$groupprefix - $($p.displayname)",
"groupTypes": [
],
"mailEnabled": false,
"mailNickname": "capExclude$(1..10000 | get-random)",
"securityEnabled": true,
}
"@
$grp = Invoke-MgGraphRequest -Method POST -uri "https://graph.microsoft.com/beta/administrativeUnits/$($au.id)/members" -ContentType 'application/json' -body $body
#add to conditional access policy
$addtoexc = @(($p.conditions.users.excludeGroups + $($grp.id)) -join("`",`""))
$body = @"
{
"conditions": {
"users": {
"excludeGroups": [
"$addtoexc"
]
}
}
}
"@
$uri = "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/$($p.id)"
Invoke-MgGraphRequest -Uri $Uri -Method PATCH -ContentType "application/json" -body $body
}