Automate creation of Settings Catalog policies in Intune with Microsoft Graph API

I have been getting really into the using the Graph API lately and let me tell you, once you open that door there is no going back. Below is what we’ll be covering in today’s post.

Table of Contents
  1. Creating the reference policy in Intune
  2. A short introduction to what the Graph Explorer is
  3. Using Graph Explorer to GET the JSON
  4. A few tips on how to read the JSON
  5. Building the JSON template
  6. Deploying the policies using Graph API
  7. Final thoughts and a little disclaimer

Creating the reference policy in Intune

In order to get the JSON file that we need to automate the policy creation we must first create a reference policy in the Intune portal. I won’t go into detail on this since most of you probably know how to create a settings catalog policy in Intune haha. For this example I’ll use a OneDrive policy that looks like this:

A short introduction to what the Graph Explorer is

If you’re new to the Graph Explorer it’s basically a way to send GET, POST, PUT, PATCH and DELETE requests using Microsoft Graph API and view the results on the web. Another way of describing it is that the Graph API is what is actually going on behind the GUI in the Intune portal. Everytime you click a button or write a value in a policy in Intune, it’s all Microsoft Graph behind it.

We can call the graph API by connecting to Microsoft Graph using the Powershell module with appropriate scopes and then calling Invoke-MgGraphRequest -Method ‘INSERT METHOD HERE’ (Where the method is GET, POST, PUT, PATCH or DELETE). You’ll se it live further down the post when deploying the policy using Powershell.

How to use it:

Go to https://developer.microsoft.com/en-us/graph/graph-explorer

Sign in with with your global administrator account and grant the necessary permissions and we are ready to go!

Using Graph Explorer to GET the JSON

So in this scenario there is a few URL’s that are important that we can use:

URL: https://graph.microsoft.com/beta/deviceManagement/configurationPolicies

This first URL lists all your policies (not just settings catalog, but all your policies). This won’t expand the actual configurations of each policy. Each policy block ends with }, and I recommend looking at the “name”: in each block to identify where a policy starts and ends.

What we need to get is the policy ID which is found in the policy block where it says “id”. In our case we are using the OneDrive policy so I scroll down until I found that block and the appropriate ID.

You can also find the Id by going to the policy in the Intune portal and looking in the URL:

In order to get our specific OneDrive policy we simply copy that PolicyId into the Graph Explorer URL and add /settings at the end to get the full configuration settings. Your URL should look like this:

URL: https://graph.microsoft.com/beta/deviceManagement/configurationPolicies/{policyID}/settings

Once we hit Run on the GET query we end up with something like this:

A few tips on how to read the JSON

Each setting is divided into a block containing the data type and the value of the actual setting and each block has a unique Id going from 0 and onwards. If you are following along with the exact same OneDrive policy as me you should have 8 different blocks since we have eight different settings (as you can see below):

The easiest way to read this is by identifying the where the first { and last } is (the last one always has a , at the end if there is another setting after it. Also look for the Id right after the first {. Let’s look at the block with id 3 for reference:

      {
            "id": "3",
            "settingInstance": {
                "@odata.type": "#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance",
                "settingDefinitionId": "device_vendor_msft_policy_config_onedrivengscv2~policy~onedrivengsc_kfmoptinwithwizard",
                "settingInstanceTemplateReference": null,
                "choiceSettingValue": {
                    "settingValueTemplateReference": null,
                    "value": "device_vendor_msft_policy_config_onedrivengscv2~policy~onedrivengsc_kfmoptinwithwizard_1",
                    "children": [
                        {
                            "@odata.type": "#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance",
                            "settingDefinitionId": "device_vendor_msft_policy_config_onedrivengscv2~policy~onedrivengsc_kfmoptinwithwizard_kfmoptinwithwizard_textbox",
                            "settingInstanceTemplateReference": null,
                            "simpleSettingValue": {
                                "@odata.type": "#microsoft.graph.deviceManagementConfigurationStringSettingValue",
                                "settingValueTemplateReference": null,
                                "value": "TENANT ID HERE"
                            }
                        }
                    ]
                }
            }
        },Code language: JavaScript (javascript)

This block above represents the Prompt users to move known folders to OneDrive settings which is enabled. As you can see below each value inside the actual setting is divided by an odata.type. ChoiceSettingInstance is where the value is 0 or 1 which tells us if it’s enabled or disabled (green). If it’s enabled we have a child setting which is the SimpleSettingsInstance where the value is the tenant ID (orange).

Building the JSON template

The first part of the JSON template that we need is a short header for the basics like name, description, policy type etc. It looks like this:

{
  "name": "Graph - OneDrive",
  "description": "Known folder move and sync settings",
  "platforms": "windows10",
  "technologies": "mdm",
  "roleScopeTagIds": [ "0" ],
  "settings": [Code language: JSON / JSON with Comments (json)

After that we copy everything from the first block in Graph explorer like above:

Your JSON should now look like this:

For demonstration purposes we will turn off the Prompt users to move known folders to OneDrive settings in our JSON-file. We do this by changing the 1 to a 0 and removing the , at the end in the block with id 3. Since it’s now disabled we also remove the block containing the child setting with the tenant ID:

Create a folder called GraphSettingsCatalog (or something else if you prefer). Inside that folder create another folder called configs where you save this and all your other JSON files for the settings catalog policies you wish to deploy. If you want to you can also save a template with the header in the root folder like I did to make it easier when creating multiple JSON’s.

Deploying the policies using Graph API

You can use the steps above to create as many JSON files as you like and add to the configs folder. In my case I also added a Bitlocker policy just for demonstration. The DeploySettingsCatalog.ps1 script that you see on the picture above looks like this:

<#
Script created by Tobias Eriksson. https://www.tob-it.se/

1. Create reference policy
2. Get the JSON template https://graph.microsoft.com/beta/deviceManagement/configurationPolicies/{policyID}/settings
3. Create the JSON file and add it to the configs folder
#>

# Connect to Microsoft Graph
Connect-MgGraph -Scopes DeviceManagementConfiguration.ReadWrite.All

# Path to your JSON configs
$currentPath = Get-Location
$configPath = "$currentPath\configs"

# Loop through all JSON files in the configs folder
Get-ChildItem -Path $configPath -Filter *.json | ForEach-Object {
    $file = $_.FullName
    $name = $_.BaseName  

    try {
        Invoke-MgGraphRequest -Method POST `
            -Uri "https://graph.microsoft.com/beta/deviceManagement/configurationPolicies" `
            -Body (Get-Content $file -Raw) `
            -ContentType "application/json" | Out-Null

        Write-Host "Created policy from $name.json" -ForegroundColor Green
    }
    catch {
        Write-Host "Failed to create policy from $name.json" -ForegroundColor Red
        Write-Host "Exception: $($_.Exception.Message)" -ForegroundColor Red
        if ($_.ErrorDetails.Message) {
            Write-Host "Graph error: $($_.ErrorDetails.Message)" -ForegroundColor Red
        }
    }
}

Code language: PHP (php)

The script above basically loops through the configs folder and does a POST request to the Graph API to create each policy. If there’s an error in Powershell or in Graph that will be displayed.

Make sure you run it from the root folder GraphSettingsCatalog (or whatever you named your folder). When we run the script we will be presented with each policy that was successfully created:

If we look in Intune we can see both policies have been created:

Just for show, here is the new OneDrive policy that we created using the reference policy and as you can see the Prompt users to move known folders to OneDrive settings is now disabled:

Final thoughts and a little disclaimer

I think this is a really good way and efficient way to automate the creation of staple Settings catalog policies when deploying them in different enviornments. The disclaimer part I wanted to mention is that this ONLY works for settings catalog policies as far as I know. You can still automate other policies but it works a little different.

The second disclaimer is that the group assignment automation is far more complex then I thought so I’m still working on a solution for that. It’s fairly straight forward if you include the policy ID in the script, but my goal is to build it solely on the JSONs and Graph API calls. I’ll get back to you on that one! Until next time!

Leave a Reply

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