Azure AD

Using PowerShell to Manage Conditional Access (CA) Policies


Microsoft provides many methods to manage a tenant’s data and users.  PowerShell is a powerful tool to manage resources, including Conditional Access Policies using a set of cmdlets in the AzureAD module.  In this article, we review the eight PowerShell cmdlets and how to use them.

**Note that both the AzureAG and AzureADPreview PowerShell modules contain these cmdlets.

PowerShell and CA Policies

First, connect to Azure Active Directory using either the AzureAD or AzureADPreview module:

After connecting, we can get a list of available PowerShell cmdlets by using these two one-liners:
GetCommand *conditional*
GetCommand *named*

Combined we get a total of eight cmdlets dealing with Conditional Access Policies and Names Location Policies:


Conditional Access Policies set conditions to determine the conditions under which users receive access to apps.  These conditions can consist of locations, one or more users, applications, platforms, and more.

Figure 1: Properties of a new Conditional Access Policy

In the following examples, we examine these conditions to see what we can configure with PowerShell.

Creating a New Conditional Access Policy

A greenfield, or new tenant, has no Conditional Access Policies.  To utilize Conditional Access, we need to build its conditions.  If Named Locations are required, we need to create the Named Location first.  Let us walk through this process using an example scenario.

Named Locations

Conditional Access Policies can contain Named Locations that correspond to physical locations in an organization’s environment. Named Locations can be Physical locations with their corresponding IP subnet/range or a single country/a set of countries.  We can use Named Locations to provide a condition that controls where users are prompted (or not prompted) for MFA or other optional actions.   Included in the Azure AD Module, we saw that there are four PowerShell cmdlets for managing Named Locations and run the typical gamut of Get, New, Remove and Set PowerShell verbs.

In a new or Greenfield Azure AD, there are no Named Locations that can be used by Conditional Access and we need to either create these in Azure AD or with PowerShell.  To create a new Named Location policy, we need to use the New-AzureADMSNamedLocationPolicy cmdlet.

When creating a new Named location, we need to keep a couple of things in mind:

  • Display Name is required
  • Need to choose either an IP range or a list of countries as this determines the type of Named Location we are creating.

For the first Named Location, we can use some base criteria – Chicago Office, IP Range of with a subnet mask of 16 bits and we will mark this location as a trusted location. A second location can also be created for a New York Office, with an IP range of and the same subnet mask of 16 bits. PowerShell is required to create the Named Location.  Notice that there is an MS Graph object for the IP subnet of the office in the example below.

IT wants a Conditional Access Policy to force multi-factor authentication (MFA) for all cloud apps unless users access apps from two locations.  The locations are both physical offices in Chicago and New York, with subnets of and, respectively.  We will first create the two Named Locations using New-AzureADMSNamedLocationPolicy and then create a new CA Policy using New-AzureADMSConditionalAccessPolicy to reference the locations:
$CHISubnet = NewObject TypeName Microsoft.Open.MSGraph.Model.IpRange
$CHISubnet.cidrAddress = ‘’
NewAzureADMSNamedLocationPolicy OdataType “#microsoft.graph.ipNamedLocation” DisplayName ‘Chicago Office’ IsTrusted $True IpRanges $CHISubnet
$NYSubnet = NewObject TypeName Microsoft.Open.MSGraph.Model.IpRange
$NYSubnet.cidrAddress = ‘’
NewAzureADMSNamedLocationPolicy OdataType “#microsoft.graph.ipNamedLocation” DisplayName ‘New York Office’ IsTrusted $True IpRanges $NYSubnet

We can validate the properties of the locations with the Get-AzureADMSNamedLocationPolicy cmdlet, which we should do before proceeding:

Figure 2: New Named Locations and the configured settings in the red rectangles.

** To be fair, the same output is also generated when creating a Named Location, but the above illustrates what can be seen with the Get-* portion of the Named Location cmdlets.

With the Named Locations created, we can now use these into a CA Policy (keep in mind there are a lot of settings to a CA Policy).  First, we need an object to hold the Condition for the CA Policy (Applications, Users, and Locations). Breakdown of the available conditions available in ConditionalAccessConditionSet is defined here.
$CAConditions = NewObject TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet
$CAConditions.Applications = NewObject TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition
$CAConditions.Applications.IncludeApplications = ‘All’

In this section, we define the users to apply the Conditional Access Policy to (Users.ExcludeUsers) as well as any users we wish to exclude (Users.ExcludeUsers).  In this case, the excluded user is a Break Glass account that is excluded from any policies we define and is shown below as the Object GUID for the user in Azure AD.  The GUIDs for the locations are in the ID field as seen in Figure 2.
$CAConditions.Users = NewObject TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition
$CAConditions.Users.IncludeUsers = ‘All’
$CAConditions.Users.ExcludeUsers = ‘22561a78-a72e-4d39-898d-cd7c57c84ca6’
$CAConditions.Locations = NewObject TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessLocationCondition
$CAConditions.Locations.IncludeLocations = ‘0743ff81-cea0-40d2-b0f0-4028cdc1c61a’,‘0f0c7a7f-4863-480e-9b71-d8f9eddb37e4’

** Be careful with the ‘All’ Applications AND ‘All’ user settings as this does affect the Azure AD Portal as well, which means you could get locked out of the portal and not able to change your CA Policies.  Make sure to have a Break Glass Account created and excluded as shown here [Users.ExcludeUsers].  For more information on Break Glass Accounts, refer to this blog post.

Next, we need to configure Grant Controls for the MFA requirement.  Like the Conditions above we also need a Graph object and provide an operator (‘Or’ / ‘And’) as well as the control, in our case MFA:
$CAControls = NewObject TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessGrantControls
$CAControls._Operator = “OR”
$CAControls.BuiltInControls = “Mfa”

** A list of available BuiltInControls can be found here.

Summary of Policy Settings:

  • Applies to all Cloud Apps
  • Applied to all users in Azure AD
  • Excluded from applying to one account
  • Enforces MFA for these users and these apps
  • Two Names Locations included, where MFA will not be enforced

We now have our $CAConditions object and $CAControls object populated with the required settings and can use this to create a CA Policy per our initial requirements:
NewAzureADMSConditionalAccessPolicy DisplayName “CloudApps-MFA-CorpWide” State “Enabled” Conditions $CAConditions GrantControls $CAControls

Unfortunately, all the settings put in place for this CA Policy are obfuscated by ‘System.Collections’ as the properties contain complex data sets. To validate settings for the CA Policy we must pick apart each condition to see what is present. Applications, Users and Locations are all sub-properties of the Conditions property on a CA Policy; thus we can break each of these sections down like so:



In all cases, Applications, Users and Locations are listed in the Conditional Access Policies as ObjectIds.  If a report were generated for management, additional PowerShell queries would be needed to convert these values to names.  Converting the ObjectIds to names would also help with verification or documenting/auditing CA Policies.

Altering an Existing Conditional Access Policy

Now that we have a CA Policy in place, we can use PowerShell to update Applications, Users, Locations and Controls as well as other unconfigured items like Platforms and Sign-In Risk.

Changing the Enforcement of a CA Policy
One change that could be implemented is changing the state of the CA Policy.  CA Policies have three states: EnabledForReportingButNotEnforced, Enabled and Disabled.  For example, if a new CA Policy is in place and users are prompted for MFA when inside a corporate location, then the policy could potentially be disabled or set to report only until troubleshooting is performed:
SetAzureADMSConditionalAccessPolicy PolicyId 21bdd8c1bb5c40d1a4de926888c69163 State Disabled
SetAzureADMSConditionalAccessPolicy PolicyId 21bdd8c1bb5c40d1a4de926888c69163 State EnabledForReportingButNotEnforced

With the policy effectively disabled, IT can now make changes to the policy, validate them, and then re-enable the policy:
SetAzureADMSConditionalAccessPolicy PolicyId 21bdd8c1bb5c40d1a4de926888c69163 State Enabled

Changing CA Policy Controls
In the previous example, there is a requirement for an MFA prompt when using a cloud app and connecting from outside the two Named Locations.   These controls can also be adjusted if additional security requirements are needed or possible alternatives (Azure AD Joined / Compliance).  Controls on CA Policies can also be combined (AND) versus the one control (OR) that was in the previous example.

For example, if we want to add that when a user accesses a cloud app, while external, they need to do so from a Compliant Device AND they must be prompted for MFA, we can do so by creating a new Control object and then apply this to the existing CA Policy.  A Compliant Device is a device that meets a specified list of criteria that is predefined like OS version level, not jailbroken, etc. First the Controls:
$CAControls = NewObject TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessGrantControls
$CAControls._Operator = “AND”
$CAControls.BuiltInControls = “Mfa”,“CompliantDevice”

Notice that we have an AND operator, which declares that both Controls need to be true.  Also, of note, is that the configured Controls are MFA and a Compliant Device.  These controls are then applied to an existing CA Policy, overwriting any existing settings:
SetAzureADMSConditionalAccessPolicy PolicyId 21bdd8c1bb5c40d1a4de926888c69163s GrantControls $CAControls




We can now place this in a one-liner like so:
RemoveAzureADMSConditionalAccessPolicy PolicyId 7ac2fceed5bd4003ad105dfa838417da

No prompt is given, so be careful with the removal of CA Policies.

Named Locations

As mentioned previously, Conditional Access Policies use the concept of Named Locations to correspond to physical locations in an organization’s environment. We can use the Get-AzureADMSNamedLocationPolicy to compare what is shown in PowerShell and what is displayed in the Azure AD portal for Named locations. This is useful for validating a configuration as well as understanding any differences between the two displays:

Figure 3: Breakdown of a Named location in PowerShell and in the Conditional Access section of AzureAD.

Modify Existing Named Location

Organizations change over time which might mean that changes are needed for named locations. For example, you might need to rename locations, add subnets, remove subnets, mark them as trusted, or remove the trust. All these changes can be performed with the Set-AzureADMSNamedLocationPolicy cmdlet. Let us see what it takes to make each of these changes:

Change Named Location ‘Name’
SetAzureADMSNamedLocationPolicy PolicyId 0743ff81cea040d2b0f04028cdc1c61a DisplayName ‘Chicago Loop Office’
Change IP Range
$ipRanges = NewObject TypeName Microsoft.Open.MSGraph.Model.IpRange
$ipRanges.cidrAddress = ‘’
SetAzureADMSNamedLocationPolicy PolicyId 0743ff81cea040d2b0f04028cdc1c61a IpRanges $ipRanges OdataType “#microsoft.graph.ipNamedLocation”
SetAzureADMSNamedLocationPolicy PolicyId 0743ff81cea040d2b0f04028cdc1c61a IsTrusted $False
SetAzureADMSNamedLocationPolicy PolicyId 0743ff81cea040d2b0f04028cdc1c61a IsTrusted $True

Removing a Named Location

When offices close or are no longer needed for a Conditional Access Policy, the Named Locations can be removed if there is a desire to do so. Leaving the Named Locations behind does not create a security risk. We first need to determine if there are any existing Conditional Access Policies that contain the location. We can pick these out from the Conditions property of the CA Policy and look at the Locations sub-property, which stores the location as a System.Collections.Generic.List:


We can reveal the GUID:

Let us assume we need to remove our Chicago Office, which is a Named Location:


The ‘Id’ value is what we can use to match to the Locations.IncludeLocations value in the CA. To find any CA Policy with this Named Location, we need to match the value like so:
$OldNamedLocationId = (GetAzureADMSNamedLocationPolicy | Where {$_.DisplayName eq ‘Chicago office’}).Id
$CAPolicies = GetAzureADMSConditionalAccessPolicy
Foreach ($CAPolicy in $CAPolicies) {
If ($OldNamedLocationId eq((($CAPolicy).Conditions).Locations).IncludeLocations) {
WriteHost “CA Policy $($CAPolicy.Id) contains the Named Location.”

We may have only one location, or we may have multiple locations, but all matching entries will be displayed:
CA Policy 4e7dac6d-d471-483f-9677-46407acaa3f5 contains the Named Location.
We can decide to either remove the policy or just remove the Named Location. If the Named Location is the only one, then we would need to replace it to keep the CA Policy. For this example, we will replace the location with another Named Location. First, find any non-Chicago Office Named Locations:
GetAzureADMSNamedLocationPolicy | Where {$_.DisplayName ne ‘Chicago office’} | ft DisplayName,Id

We then use the ID from this location to replace the one we need to remove:
$OldNamedLocationId = (GetAzureADMSNamedLocationPolicy | Where {$_.DisplayName eq ‘Chicago office’}).Id
$NewNamedLocationId = (GetAzureADMSNamedLocationPolicy | Where {$_.DisplayName eq ‘LA Office Office’}).Id
$conditions = NewObject TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet
$conditions.Locations = NewObject TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessLocationCondition
$conditions.Locations.IncludeLocations = “$NewNamedLocationId”
Foreach ($CAPolicy in $CAPolicies) {
If ($OldNamedLocationIdeq ((($CAPolicy).Conditions).Locations).IncludeLocations) {
SetAzureADMSConditionalAccessPolicy PolicyId $($CAPolicy.ID) Conditions $Conditions

Now we re-run the same code block we ran to find the CA Policies with the Named Location:
$NamedLocationId = (GetAzureADMSNamedLocationPolicy | Where {$_.DisplayName eq ‘Chicago office’}).Id
$CAPolicies = GetAzureADMSConditionalAccessPolicy
Foreach ($CAPolicy in $CAPolicies) {
If ($NamedLocationId eq((($CAPolicy).Conditions).Locations).IncludeLocations) {
WriteHost “CA Policy $($CAPolicy.ID) contains the Named Location.”

Now no results are returned, and we are safe to remove the Named Location:

**Tip: Make sure to remove a Named Location from a Conditional Access Policy
If we try to remove a Named Location that is defined in a Conditional Access Policy, an error is generated. This is because the Named Location is attached to the Conditional Access policy and needs to be removed first.

Figure 4: Attempting to remove a Named Location before removing it from a Conditional Access policy.

Final Thoughts

From the article, we can see that Microsoft provides a set of PowerShell cmdlets that provide a convenient access point to Conditional Access Policies. These CA Policies can be created, modified, and even removed as with these cmdlets. We also have cmdlets to create Named Locations, which can, in turn, be used by the Conditional Access Policies. Potential uses for these cmdlets span from creation and management of CA Policies to documentation and auditing of Policies for security personnel/consultants needing to verify the security stance of an organization. Make sure to read the documentation links provided in this article as well as the Get-Help for the cmdlets for guidance on values to be used for the various moving parts of a policy – Locations, Platforms, Grant Controls, Session controls, and more.

Source Practical365

Chioma Ugochukwu

The author Chioma Ugochukwu

Leave a Response