Document AzureAD Conditional Access Policies

Hi All,

I had the "pleasure" again this week to Document the Azure AD Policies.
Making several Screenshots in the Azure AD Portal seemed not the best way.



MSGraph: List Conditional Access policies

So tried to use the Microsoft Graph Explorer https://aka.ms/ge
You need the Permission: Policy.Read.All

https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies


While using the JSON could be one way. It's not very good if you have to Document it in a Word Document right.

I tried to use the Microsoft.Graph PowerShell Module

Import-Module Microsoft.Graph.Identity.SignIns
Connect-MgGraph -Scopes Policy.Read.All
$CAP = Get-MgIdentityConditionalAccessPolicy
$CAP



As you can see the Conditions, GrantControls and SessionControls are dedicated Objects

$CAP[1] | fl


If we dig down the Conditions more Objects appear

$CAP[1].Conditions | fl


And again one more Layer down in Applications we can find the Values

$CAP[1].Conditions.Applications | fl


Grant Controls are very staight forward

$CAP[1].GrantControls | fl



The Session Control has again multiple Objects to dig down

$CAP[1].SessionControls | fl


I came up with the Idea of using the Layers as Labels with "_"  and the Expression to get the Values

$CAP[1] | select Id, DisplayName, State, `
@{Label = "Conditions_Applications_ExcludeApplications"; Expression = { $_.Conditions.Applications.ExcludeApplications}}, `
@{Label = "Conditions_Applications_IncludeApplications"; Expression = { $_.Conditions.Applications.IncludeApplications}}, `
@{Label = "Conditions_Applications_IncludeAuthenticationContextClassReferences"; Expression = { $_.Conditions.Applications.IncludeAuthenticationContextClassReferences}}, `
@{Label = "Conditions_Applications_IncludeUserActions"; Expression = { $_.Conditions.Applications.IncludeUserActions}}, `
@{Label = "Conditions_Applications_AdditionalProperties"; Expression = { $_.Conditions.Applications.AdditionalProperties}}, `
@{Label = "Conditions_ClientAppTypes"; Expression = { $_.Conditions.ClientAppTypes}}, `
@{Label = "Conditions_ClientApplications_ExcludeServicePrincipals"; Expression = { $_.Conditions.ClientApplications.ExcludeServicePrincipals}}, `
@{Label = "Conditions_ClientApplications_IncludeServicePrincipals"; Expression = { $_.Conditions.ClientApplications.IncludeServicePrincipals}}, `
@{Label = "Conditions_Devices_DeviceFilter_Mode"; Expression = { $_.Conditions.Devices.DeviceFilter.Mode}}, `
@{Label = "Conditions_Devices_DeviceFilter_Rule"; Expression = { $_.Conditions.Devices.DeviceFilter.Rule}}, `
@{Label = "Conditions_Devices_DeviceFilter_AdditionalProperties"; Expression = { $_.Conditions.Devices.DeviceFilter.AdditionalProperties}}, `
@{Label = "Conditions_Locations_ExcludeLocations"; Expression = { $_.Conditions.Locations.ExcludeLocations}}, `
@{Label = "Conditions_Locations_IncludeLocations"; Expression = { $_.Conditions.Locations.IncludeLocations}}, `
@{Label = "Conditions_Platforms_ExcludePlatforms"; Expression = { $_.Conditions.Platforms.ExcludePlatforms}}, `
@{Label = "Conditions_Platforms_IncludePlatforms"; Expression = { $_.Conditions.Platforms.IncludePlatforms}}, `
@{Label = "Conditions_Platforms_AdditionalProperties"; Expression = { $_.Conditions.Platforms.AdditionalProperties}}, `
@{Label = "Conditions_ServicePrincipalRiskLevels"; Expression = { $_.Conditions.ServicePrincipalRiskLevels}}, `
@{Label = "Conditions_SignInRiskLevels"; Expression = { $_.Conditions.SignInRiskLevels}}, `
@{Label = "Conditions_UserRiskLevels"; Expression = { $_.Conditions.UserRiskLevels}}, `
@{Label = "Conditions_users_ExcludeGroups"; Expression = { $_.Conditions.Users.ExcludeGroups}}, `
@{Label = "Conditions_users_ExcludeRoles"; Expression = { $_.Conditions.Users.ExcludeRoles}}, `
@{Label = "Conditions_users_ExcludeUsers"; Expression = { $_.Conditions.Users.ExcludeUsers}}, `
@{Label = "Conditions_users_IncludeGroups"; Expression = { $_.Conditions.Users.IncludeGroups}}, `
@{Label = "Conditions_users_IncludeRoles"; Expression = { $_.Conditions.Users.IncludeRoles}}, `
@{Label = "Conditions_users_IncludeUsers"; Expression = { $_.Conditions.Users.IncludeUsers}}, `
@{Label = "Conditions_users_AdditionalProperties"; Expression = { $_.Conditions.Users.AdditionalProperties}}, `
@{Label = "Conditions_AdditionalProperties"; Expression = { $_.Conditions.AdditionalProperties}}, `
@{Label = "SessionControls_ApplicationEnforcedRestrictions_IsEnabled"; Expression = { $_.SessionControls.ApplicationEnforcedRestrictions.IsEnabled}}, `
@{Label = "SessionControls_ApplicationEnforcedRestrictions_AdditionalProperties"; Expression = { $_.SessionControls.ApplicationEnforcedRestrictions.AdditionalProperties}}, `
@{Label = "SessionControls_CloudAppSecurity_CloudAppSecurityType"; Expression = { $_.SessionControls.CloudAppSecurity.CloudAppSecurityType}}, `
@{Label = "SessionControls_CloudAppSecurity_IsEnabled"; Expression = { $_.SessionControls.CloudAppSecurity.IsEnabled}}, `
@{Label = "SessionControls_CloudAppSecurity_AdditionalProperties"; Expression = { $_.SessionControls.CloudAppSecurity.AdditionalProperties}}, `
@{Label = "SessionControls_DisableResilienceDefaults"; Expression = { $_.SessionControls.DisableResilienceDefaults}}, `
@{Label = "SessionControls_PersistentBrowser_IsEnabled"; Expression = { $_.SessionControls.PersistentBrowser.IsEnabled}}, `
@{Label = "SessionControls_PersistentBrowser_Mode"; Expression = { $_.SessionControls.PersistentBrowser.Mode}}, `
@{Label = "SessionControls_PersistentBrowser_AdditionalProperties"; Expression = { $_.SessionControls.PersistentBrowser.AdditionalProperties}}, `
@{Label = "SessionControls_SignInFrequency_AuthenticationType"; Expression = { $_.SessionControls.SignInFrequency.AuthenticationType}}, `
@{Label = "SessionControls_SignInFrequency_FrequencyInterval"; Expression = { $_.SessionControls.SignInFrequency.FrequencyInterval}}, `
@{Label = "SessionControls_SignInFrequency_IsEnabled"; Expression = { $_.SessionControls.SignInFrequency.IsEnabled}}, `
@{Label = "SessionControls_SignInFrequency_Type"; Expression = { $_.SessionControls.SignInFrequency.Type}}, `
@{Label = "SessionControls_SignInFrequency_Value"; Expression = { $_.SessionControls.SignInFrequency.Value}}, `
@{Label = "SessionControls_SignInFrequency_AdditionalProperties"; Expression = { $_.SessionControls.SignInFrequency.AdditionalProperties}}, `
@{Label = "SessionControls_AdditionalProperties"; Expression = { $_.SessionControls.AdditionalProperties}}, `
@{Label = "GrantControls_BuiltInControls"; Expression = { $_.GrantControls.BuiltInControls}}, `
@{Label = "GrantControls_Operator"; Expression = { $_.GrantControls.Operator}}, `
@{Label = "GrantControls_CustomAuthenticationFactors"; Expression = { $_.GrantControls.CustomAuthenticationFactors}}, `
@{Label = "GrantControls_TermsOfUse"; Expression = { $_.GrantControls.TermsOfUse}}




Looks better, but still does not solve the Problem of:
  • Applications are displayed with the ID (No reference what Application is used)
  • User/Group/Roles are displayed with the ObjectID (DisplayName would help here)

Update 05.02.2023
Some People mentioned "DCToolbox"
So i'll gave it a Shot

Find-Module DCToolbox
Install-Module DCToolbox



List all the Commands of the Module

Get-Command -Module DCToolbox



For the Export of the Conditional Access Policies you need an Azure AD Application with a ClientSecret.
In Addition you need another Module:
Install-Module ImportExcel

New-DCConditionalAccessPolicyDesignReport -ClientID <ClientID> -ClientSecret <ClientSecret>



I was finnaly able to Export to Excel



Took me a while to figure out the needet Permissions.
  • Agreement.Read.All
  • Application.Read.All
  • Directory.Read.All
  • Group.Read.All
  • Policy.Read.All
  • Policy.ReadWrite.ConditionalAccess
  • User.Read
  • user.Read.All


It's a wide Excel Sheet with Columns up to "Y"
It did resolve the Excluded Users but with no Delimiter.
Included Roles where mostly not resolved and also no Delimiter



Another suggestion was


Needs to run in the C:\Scripts Folder due Output is hardcoded that way (can be fixed easy)
Still uses the AzureAD Commandlet's that will be depreciated in Summer 2023
Resolves Names of Users, Roles (sometimes) and Network Locations.





Update 15.02.2023
I've forked the CA-Export from https://github.com/dougsbaker/CA-Export to https://github.com/BohrenAn/CA-Export and fixed the MSGraph Querys and reorganized the HTML Output to fit the Conditional Access Portal



If not already connected the Script will connect MgGraph to the Beta Endpoint and use the Scopes documented below

Select-MgProfile -Name "beta"
Connect-MgGraph -Scopes 'Policy.Read.All', 'Directory.Read.All','Application.Read.All'


To run the Script use this Command

.\Export-CaPolicy.MSGraph.ps1







How do you document the Conditional Access Policies?

Regards
Andres Bohren