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"