Conditional Access “To Go”

Conditional Access “To Go”

This blog will be about automating your Conditional Access Rules with Powershell and some troubleshooting withe the new-AzureADMSCAPolicy command

Last week I published an overview of the best Conditional Access policies for the SMB. It can come in handy when deploying conditional access to your customers. Hopefully, you don’t make any mistakes when configuring the policies.  Like “oops” I just locked myself out of the Tenant.

So why not creating a baseline, you can simply import in your tenant?  I have seen a lot of scripts that can do the same. You have to create an App in your tenant with some permissions. After the app has been created you have to change the ID (from the app) in the deployment script.

No, no, no sir… I like to have my conditional access “to go”

UPDATE 03-06-2021

Instead of using invoke restmethod with Powershell you could also use New-AzureADMSConditionalAccessPolicy. Of course, I will show you both options.

So I am going to divide this blog in multiple Parts:

1.Using the new-AzureADMSConditionalAccessPolicy

2.Troubleshooting the AzureADMSConditionalAccessPolicy

3.Changing the existing Ca rules to remove the device state

4.Invoke-Restmethod (which works with device state exclusions)

1.Using New-AzureADMSConditionalAccessPolicy

With the connect-azuread module from July 2020 it’s possible to use the new-azureadmsconditionalaccesspolicy to create new Conditional Access rules.

PowerShell Gallery | AzureAD

Manually creating new rules can be a little bit hard..

New-AzureADMSConditionalAccessPolicy -DisplayName “CA0002: Require MFA for medium + sign-in risk” -State “enabledForReportingButNotEnforced” -Conditions $conditions -GrantControls $controls

As shown above, you will need to specify the conditions and controls. Maybe exporting your current configuration is a way better option so you don’t need to spend you valuable time to manually create them.

Backup Script


$AllPolicies = Get-AzureADMSConditionalAccessPolicy

foreach ($Policy in $AllPolicies) {
    Write-Output "Backing up $($Policy.DisplayName)"
    $PolicyJSON = $Policy | ConvertTo-Json -Depth 6
    $PolicyJSON | Out-File "c:\carules\$($Policy.Id).json"

Running this script will export all existing policies into separate JSON files with the config in them. Let’s take a look how the JSON

When you have your baseline configured (please make sure the state is configured to disabled!) you can import it to another tenant with this PowerShell script

Restore Script


$BackupJsons = Get-ChildItem C:\install\CA -Recurse -Include *.json
foreach ($Json in $BackupJsons) {

    $policy = Get-Content $Json.FullName | ConvertFrom-Json

    # Create objects for the conditions and GrantControls
    [Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet]$Conditions = $Policy.Conditions
    [Microsoft.Open.MSGraph.Model.ConditionalAccessGrantControls]$GrantControls = $Policy.GrantControls
    [Microsoft.Open.MSGraph.Model.ConditionalAccessSessionControls]$SessionControls = $Policy.SessionControls
    # Create an object for the users. 
    # By going through the members we only add properties that are not null
    $OldUsers = $Policy.Conditions.Users
    $UserMembers = $OldUsers | Get-Member -MemberType NoteProperty
    $Users = New-Object Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition
    foreach ($member in $UserMembers) {
        if (-not[string]::IsNullOrEmpty($OldUsers.$($member.Name))) {
            $Users.($member.Name) = ($OldUsers.$($member.Name))
    $Conditions.Users = $Users

    # Do the same thing for the applications
    $OldApplications = $Policy.Conditions.Applications
    $ApplicationMembers = $OldApplications | Get-Member -MemberType NoteProperty
    $Applications = New-Object Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition
    foreach ($member in $ApplicationMembers) {
        if (-not[string]::IsNullOrEmpty($OldApplications.$($member.Name))) {
            $Applications.($member.Name) = ($OldApplications.$($member.Name))
    $Conditions.Applications = $Applications
    $NewDisplayName = $Prefix + $Policy.DisplayName
    $Parameters = @{
        DisplayName     = $NewDisplayName
        State           = $policy.State
        Conditions      = $Conditions
        GrantControls   = $GrantControls
        SessionControls = $SessionControls

   $null = New-AzureADMSConditionalAccessPolicy @Parameters

2.Troubleshooting the restore script

But unfortunately, some Conditional access policies can’t be imported? So here comes the troubleshooting part. The first error.

After checking the JSON file which was exported I noticed the values were missing to include or exlude devicestates.

So I entered them manually and opened Fiddler to take a good look what Microsoft has to say about the JSON now.

Okay? Another error I tried to google it, but nothing usefull was found. Except this “opened issue”

after digging into the restore script I noticed the ConditionalAccessConditionset has the wrong deviceconditions configured

Taking a look at what microsoft has to tell about the conditions.

I guess we are missing the device’s property…When looking at the beta, it exists of course.

conditionalAccessConditionSet resource type – Microsoft Graph beta | Microsoft Docs

But for now, it’s not going to work to specify the DeviceConditions because the Microsoft Graph Model is telling us to specify the IncludeDeviceStates even when it will fail after you want to import the rule!

The next thing I thought was a wise thing to do, is to update the AzureAd Powershell module. but after updating….. the whole device’s property is gone.

3. Changing the existing CA rules

UPDATE 05-06-2021

After a talk with Alex Fields I realized that I could alter some of the ca Rules so it won't require the devicestate.

Explanation about the block sharepoint/exchange rules:

When you are preventing/blocking downloads from SharePoint or Exchange online you really don’t need to specify the exclusion of the compliant device because the restrictions already state that unmanaged devices can’t download, this is based on the properties set on the Sharepoint site or in Exchange Online

Explanation about the required MFA on unmanaged devices:

You can just select the: “Require MFA” or “Require Compliant Devices” and only require one of the selected controls. Just say it up out loud and you will get the Point. So when your device is compliant… it does not need MFA

Please note: The only 2 rules which I don’t get to work, are 2 block rules. To block all devices which are not in a trusted location/country and the never persistent browser on unmanaged devices.

4. Invoke-Restmethod

Even when there is an official PowerShell command available I would still use the possibility to use the invoke-restmethod. You can use Fiddler to find the settings/JSON you will need

So I created a very simple Powershell script, which can be deployed to any tenant within a few seconds. (The CA Rules are Disabled by default!!)

Here is a Video to see the deployment in action

You will notice this option has no problems at all when it is importing CA rules with specific device state excluded or included.


In my opinion not using conditional access is just like buying a very expensive television and keeping your front door open when you are on vacation. You will need to configure it! Now you have got 2 options to deploy them

Homer Simpson GIF - Homer Simpson Sneaky - Discover & Share GIFs

6 thoughts on “Conditional Access “To Go”

  1. Pingback: Along came MCAS Automation - Call4Cloud
  2. Hello, a big thank you for the very informative and helpful information in Mcas. I am learning a great deal by following your articles.
    Do you mind sharing the PS script you mention in the article about automating conditional access?
    Thank you very much.

  3. Pingback: Basic Authentication and the Last Crusade - Call4Cloud
  4. HI rudyooms,

    Likwise I’d love to look at the code.

    I have to depoly CA a lot and the manual process / graph is a pain.

    Would you share?

    Kind regards

  5. Ziet er (wederom) super interessant uit! Ik ga binnenkort wat spelen met Azure. Zou je mij je scriptje kunnen mailen bij gelegenheid? Ben benieuwd!

Leave a Reply

Your email address will not be published. Required fields are marked *

66  +    =  67