How to Create Conditional Access Policies with Microsoft Graph PowerShell

  • Post author:
  • Post category:Microsoft Graph
  • Post last modified:September 10, 2023
  • Reading time:8 mins read

Conditional Access policies enable admins to configure and enforce baseline levels of security for our tenants. Admins may often need to configure multiple standard policies to different tenants or just programmatically with PowerShell. 

In this tutorial, I am going to show you how to configure Conditional Access policies using Microsoft Graph PowerShell.

About the New-MgIdentityConditionalAccessPolicy cmdlet

The New-MgIdentityConditionalAccessPolicy command is found within Microsoft.Graph.Identity.SignIns module and is used to create new Conditional Access policies in Microsoft Entra.

There are limited parameters made available with this cmdlet, which means not every setting can be defined with its own parameter. Instead, all settings need to be defined in a hash-table which is then parsed into the -BodyParameter parameter.

If you haven’t installed the Microsoft Graph PowerShell modules, check out my full tutorial for installing Microsoft Graph PowerShell: https://ourcloudnetwork.com/how-to-install-the-microsoft-graph-powershell-sdk/

Permissions required to create new Conditional Access policies

The primary permission needed to create policies is the Policy.ReadWrite.ConditionalAccess API permissions. However, it doesn’t do exactly what is expected… although you can use this permission to create new policies, it will not allow you to read all policies once it has been created.

Two other policies provide additional levels of access, enabling you to read policies or policy settings, these are:

  • Policy.Read.All
  • Application.Read.All

A full breakdown of the permissions and settings for the New-MgIdentityConditionalAccessPolicy cmdlet can be seen with the following command:

Find-MgGraphCommand New-MgIdentityConditionalAccessPolicy | fl

Your output will look like the following:

Command     : New-MgIdentityConditionalAccessPolicy
Module      : Identity.SignIns
APIVersion  : v1.0
Method      : POST
URI         : /identity/conditionalAccess/policies
OutputType  : IMicrosoftGraphConditionalAccessPolicy
Variants    : {Create, CreateExpanded}
Permissions : {Application.Read.All, Policy.Read.All, Policy.ReadWrite.ConditionalAccess}

For more information on finding permissions for use with Microsoft Graph PowerShell, check out my detailed tutorial here: https://ourcloudnetwork.com/how-to-find-permissions-for-microsoft-graph-powershell/

New-MgIdentityConditionalAccessPolicy Conditional Access Policy example

Start by connecting to Microsoft Graph PowerShell using the necessary permission scopes to allow you to create new policies and read all policy information:

Connect-MgGraph -scopes Policy.Read.All, Policy.ReadWrite.ConditionalAccess

You can then use the following example code to create a new policy named ‘MFA for all users’ with some basic settings:

  • Target all users
  • Target all cloud apps
  • Require MFA
  • Enabled for reporting only
$body = @{
  displayName = "MFA for all users "
  state = "enabledForReportingButNotEnforced"
  conditions = @{
    applications = @{
      includeApplications = @(
        "All"
      )
    }
    users = @{
      includeUsers = @(
        "All"
      )
    }
    clientAppTypes = @(
      "all"
    )
  }
    grantControls = @{
    operator = "AND"
    builtInControls = @(
      "mfa"
    )
  }
}

New-MgIdentityConditionalAccessPolicy -BodyParameter $body

All settings for New-MgIdentityConditionalAccessPolicy

There are many different settings you can use with Conditional Access policies, as such the below code represents all of the available settings that you can define in your Conditional Access parameters:

Conditions

All conditions are to be contained in the conditions hash-table:

Conditions = {
    #Conditions here
}

users

All settings for user conditions are found below:

users = @{
			includeUsers = @(
				"All Users" #use "All user" or define mulitple user IDs
			)
			excludeUsers = @(
				"UserID" #Define the excluded users IDs
			)
			includeGroups = @(
			    "GroupID" #Define the included groups IDs
			)
			excludeGroups = @(
			    "GroupID" #Define the excluded groups IDs
			)
			includeRoles = @(
				"9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3" #Define the role IDs
			)
			excludeRoles = @(
				"b0f54661-2d74-4c50-afa3-1ec803f12efe" #Define the role IDs
			)
            includeGuestsOrExternalUsers = @{
                guestOrExternalUserTypes = "B2bCollaborationGuest,B2bCollaborationMember,B2bDirectConnectUser,InternalGuest,ServiceProvider,OtherExternalUser"
                externalTenants = @{
                    membershipKind = "all"
                } 
            } #Define the enternal and guest user types
            excludeGuestsOrExternalUsers = @{
                guestOrExternalUserTypes = "B2bCollaborationGuest,B2bCollaborationMember,B2bDirectConnectUser,InternalGuest,ServiceProvider,OtherExternalUser"
                externalTenants = @{
                    membershipKind = "all"
                } #Define the enternal and guest user types
            } #Define the enternal and guest user types
		}

Target resources

All settings for target resource conditions are found below:

	applications = @{
			includeApplications = @(
				"All" #Define all applications or the application IDs
			)
			applicationFilter = @{
                mode = "include"
                rule = "CustomSecurityAttribute.DanielWasHere_Test -eq \"Yes\""
            } #Use the web portal to create the rule syntax
			excludeApplications = @(
				"499b84ac-1321-427f-aa17-267ca6975798"
			) #Define applications by the application IDs
			includeUserActions = @(
			    "urn:user:registersecurityinfo"
			    "urn:user:registerdevice"
			) #Define either of both user actions
            includeAuthenticationContextClassReferences = @( 
                "c1"
                "c2"
            ) #Define authentication context by the ID
            globalSecureAccess = @{
                includeTrafficProfiles =  "M365"
            } #Define Global secure access profile by the profile name
		}

Platforms

All settings for platform conditions are found below:

platforms = @{
			includePlatforms = @(
				"all"
				"adroid"
				"iOS"
				"WindowsPhones"
				"Windows"
				"macOS"
				"linux"
			) #Define each platform or all platforms
			excludePlatforms = @(
				"all"
				"adroid"
				"iOS"
				"WindowsPhones"
				"Windows"
				"macOS"
				"linux"
			) #Define each platform or all platforms
		}

Locations

All settings for location conditions are found below:

locations = @{
			includeLocations = @(
			    "all"
				"AllTrusted"
				"3d46dbda-8382-466a-856d-eb00cbc6b910" #all compliant network locations
				"Custom network location ID"
			) #Define one of the above options
			excludeLocations = @(
                "AllTrusted"
				"Custom network location ID"
			) #Define one of the above options
		}

User risk and Sign-in risk

All settings for user risk and sign-in risk conditions are found below:

signInRiskLevels = @(
	"high"
	"medium"
	"low"
	"none"
) #Select one or all of the above options
UserRiskLevels = @(
	"high"
	"medium"
) #Select one or all of the above options
        signInRiskDetections = $null

Client apps

All settings for client app conditions are found below:

clientAppTypes = @(
	"browser"
	"mobileAppsAndDesktopClients"
	"exchangeActiveSync"
	"other"
) #Select on or all of the above app types

Grant controls

All settings for grant control are found below:

grantControls = @{
	operator = "OR" #Select the AND or OR operator
	builtInControls = @(
		"mfa"
		"compliantDevice"
		"domainJoinedDevice"
		"approvedApplication"
		"compliantApplication"
	) #Chose from the above options
	customAuthenticationFactors = @(
	)
	termsOfUse = @(
		"ce580154-086a-40fd-91df-8a60abac81a0"
		"7f29d675-caff-43e1-8a53-1b8516ed2075"
	) #Define ID of the terms of use policy
    authenticationStrength = @{
        id = "db443b3a-6c4e-45f5-aa9a-7819e56d2987"
    } #Define the ID of your authentication stenght (built-in or custom works)
}

Session controls

All settings for sessions controls are found below:

sessionControls = @{
	applicationEnforcedRestrictions = $null
	persistentBrowser = @{
        mode = "always" # or "never"
        isEnabled = "true"
    } #Define persistent browser settings
	cloudAppSecurity = @{
		cloudAppSecurityType = "blockDownloads" # or "MonitorOnly"
		isEnabled = $true
	} #Define cloud app security policy
    continuousAccessEvaluation = @{
        mode = "strictLocation"
    } #remove is not needed
    secureSignInSession = @{
        isEnabled = $true
        secureAppSessionMode = "notEnforced"
    } #Define token protection settings
    disableResilienceDefaults = $true
	signInFrequency = @{
		value = 4
		type = "hours"
		isEnabled = $true
	} #Define sign-in frequency settings
    globalSecureAccessFilteringProfile = $null
}

State

Use the following options to control the state of the policy:

state = "enabled"
        "disabled"
        "enabledForReportingButNotEnforced"

Leave a Reply