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.

So tried to use the Microsoft Graph Explorer

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