Duplicating Device Configuration Profiles

Brass Contributor

Duplicating Device Configuration Profiles

7/24/2019 - 13 Minutes to read


One of the highest voted feature requests in Intune UserVoice is the ability to duplicate Device Configuration profiles and for good reason.


I work in the Education sector, so I'm deploying carts of laptops to multiple classrooms in multiple schools. Generally, the whole school would have the same profiles assigned to all devices but teachers can be pretty fickle about what restrictions should and shouldn't be on their classroom's devices. So if a couple classrooms want to have one or two things changed for their carts, I'd be stuck in the portal, clicking away and comparing until I have four or five profiles that are exactly the same, aside from those tiny changes. It's a huge time suck having to do that and some setting always gets missed. Lucky us, (almost*) the entire Intune UI front end is built using Graph so anything we can do in the UI, we can also do in Graph.


Let's say that the entire school has a profile applied to all devices but one classroom wants to block the camera. To do this through the UI, we'd have to start from scratch and dual monitor or split screen two windows to have the default profile open while we configure the one-off profile. But let's see how we can do this through Graph to speed up the process and help eliminate missed settings between the two profiles.


I use two methods to view the profile through Graph. Between the two, the one that I use just depends on if I have Graph open already. If I don't have Graph open, I'll start in the portal. We'll start with that method first.


Method 1 – Using Developer Tools from your Browser


The first method, you'll be using your browser's built-in Developer Tools. For me, that's usually Chrome but I've been using the new Edge more and more lately. The good thing is since they are both built on Chromium, it's pretty much the same between the two. For this guide, I'll be using Chrome.


Navigate to Intune > Device configuration – Profiles


Screen Shot 2019-07-24 at 3.44.36 PM 1.png


Since everything in the UI is just a frontend for Graph API, every time you do something in the UI, you'll be able to see all of the REST requests made by observing Network requests from the Network tab of your DevTools. This can look a little intimidating at first but if you start recording Network requests right before you view or change something in the UI, then stop recording when you're done viewing or changing things, you'll limit the number of recorded requests to only what happened while you making the changes or viewing the profiles.


Open your browser's Developer Tools. In Chrome (called DevTools), this is done by pushing F12. Open the Network tab and make sure it's recording. You'll see the Red record button lit up.

Click on the profile you want to copy. Once the page loads, stop the Network recording.


You should now see a handful of requests listed there. These are what was happening behind the scenes as you opened the profile that you wanted to copy. We can break this down a little bit but we won't get too deep as that could be a completely separate guide by itself and I'm not an expert in RESTful APIs.


Screen Shot 2019-07-24 at 3.45.19 PM 1.png


You can see a little bit of what you need just by the name of the requests, but when you click on the requests, you'll get a lot more information.


Click on the first one listed and open the Headers tab. In that tab, you'll see Request URL under General. Let's take a look at that URL and break it down.


Screen Shot 2019-07-24 at 4.09.00 PM.png


In this case, it can be broken down like this:




So that means, "deviceManagment" is a collection that contains other collections, like "managedDeviceOverview", "detectedApps", and what we want, "deviceConfigurations". "deviceConfigurations" is the collection of, you guessed it, all your device configuration profiles. And the final part of the request URL is the ID of the device configuration profile entity that we are copying.


Now technically, that is the full URL. The question mark is the query initiator and everything after is part of the query. In our URL, the query is requesting that the returned data also includes the assignments of the profile. We don't really need that and it's usually faster to just do the assignments through the UI unless you already have the entity ID of the groups you will be assigning them to.


Screen Shot 2019-07-24 at 4.05.54 PM.png


So now that we know all that, we can move on to the next Network request in the list which should be the actual "GET" request. What we are interested in with this one, is in the Response tab. These are all the settings that are in that device configuration profile and all their properties. Now, in this view it's pretty hard to read, but we can use Graph Explorer to get the same data in a prettier format since we have the request URL.


Copy everything in the Request URL from the beginning up to the "?". Remember that the question mark and everything behind it is part of a query and is not something that we need right now.


Open https://developer.microsoft.com/en-us/graph/graph-explorer# in a browser, sign in, and read and allow access if needed (if this is your first time using Graph and no one has accepted on behalf of the organization then you'll be prompted for this).

In the Graph URL request input field, paste the Request URL that you just copied. Make sure that the HTTP verb select button is on GET and click on Run Query.


Upon success you'll get a little notification with the Status Code of 200 and a Response Preview of all the settings and their properties in JSON format. We now have all the data we need to make another profile with the exact same settings.


Screen Shot 2019-07-24 at 3.47.04 PM 1.png

Method 2 – Using Graph to find the device configuration profile


The second method is actually the one I use most since I typically have a Graph Explorer window open as one of my five opening tabs and since I'm becoming more comfortable using Graph.


Open https://developer.microsoft.com/en-us/graph/graph-explorer# in a browser and enter https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations into the Graph URL request input field, make sure that the HTTP verb select button is on GET and click on Run Query.


Untitled picture.png


How do I know this if I didn't use DevTools? The "Working with Intune in Microsoft Graph" (https://docs.microsoft.com/en-us/graph/api/resources/intune-graph-overview?view=graph-rest-1.0) doc is a pretty great reference on how to navigate your way through Graph. I have come across a few discrepancies here and there but for the most part, it's pretty solid. Using that doc, you can find out how to "list" all your device configurations.


Again, you should see "Success – Status Code 200" after the query is returned. This time, in the Response Preview body, you'll see a list of all your device configuration profiles. For me, it's a very short list; just one profile, but in a production environment, there can be a lot more. Easiest thing to do is ctrl-F to find the name of the profile you want to copy but you can save yourself a little time and get a little practice in by adding some query parameters to the end of your request URL.


We initiate the query parameter with "?" Followed by the name of the parameter. These query options are in OData V4 query language. We'll be using the "$filter" to filter out everything we don't need and only return what we do need.


As you can see in the screen shot, the "displayName" of my policy is "Default Restrictions". Since we already know the name of the policy we are going to be copying, we can use that to filter everything else out by adding ?$filter=displayName eq 'Default Restrictions'  to the end of our request URL and run the query. Now, only profiles matching that filter will be returned. Then copy the "id", and add it to the end of the request URL and run your query again.


Screen Shot 2019-07-24 at 3.47.52 PM.png


We now have the data we need to create a new profile with the same settings.

Creating the new profile


We should now be looking at a JSON formatted policy that we can copy and edit to create a new policy with. To do this, we'll need to prune out a few lines. While you can do this directly in Graph Explorer, I recommend using a smart text editor like Notepad ++ or Sublime Text.


Copy everything from the opening bracket ( { ) just above the "@odata.context" line to the closing bracket ( } ) just after your last setting. Careful here. You have to make sure you're copying everything you need. In my profile, the last setting uses brackets within the setting. It's easy to misread it and copy the bracket that closes that setting and miss the bracket the closes the entire config. Just be mindful of that.


Paste the copied text into a text editor and find the lines that you'll need to delete. You'll want to remove anything that is generated automatically like "@odata.context", "id", "lastModifiedDateTime",  "supportsScopeTags", "createdDateTime", and "version". Once those are removed, you'll want to edit the "displayName" and "description" at least, but you can also make your configuration changes here if you know what you are doing. In my case, I'll change the "displayName", "description", and "cameraBlocked" settings,


The first two setting properties are strings, while the "cameraBlocked" setting property is boolean. I'll replace displayName: "Default Restrictions" with "Custom Restrictions – City High School Room 104", description: "Standard policy for Company Windows 10 Devices" with "Modified from Default Restrictions – Block Camera", and cameraBlocked: false to true. Pay special attention to where the quotes are. There are none needed for boolean properties. Now I have my new profile in JSON format and we are ready to create the new profile using Graph.


Screen Shot 2019-07-24 at 4.18.15 PM.png


Open https://developer.microsoft.com/en-us/graph/graph-explorer and enter https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations in the URL request field. Copy and paste our newly created JSON text into the Request Body field, change the HTTP verb select button to POST, run our query and be done. Obviously, you always want to be very careful when you are running POST requests, and generally any other request that isn't a read action. 


You should now get a notification with "Success – Status Code 201" along with a Response Preview of the complete JSON data of the new profile, including the automatically created settings that were removed previously. If you refresh your Intune > Device configuration – Profiles blade, you'll see your new profile. It's always best to compare the number of Settings Configured just to be sure nothing was missed.


Screen Shot 2019-07-24 at 3.50.36 PM.png


Here you can see that the new profile has the correct name, description, and has one more setting then the Default Restrictions profile. That additional setting is the Block Camera setting.


Screen Shot 2019-07-24 at 4.24.09 PM (2).png



So you can see how we can leverage Graph to programmatically make changes to Intune. It doesn't stop with duplicating profiles either. I've used it to create hundreds of Dynamic Device Groups, assign Apps to mass groups, and much more. Graph is adding to its capabilities to manage Intune as fast as Intune is adding features. And best of all, you get to deal with Intune UI a lot less.


Follow Graph's What's new page at https://docs.microsoft.com/en-us/graph/whats-new-overview.


Follow me on Twitter: @portaldotjay


* -Thanks @jenstf  for pointing out that Intune also uses the API, "main.iam.ad.ext.azure.com". Be warned - using that API is unsupported so don't dink around in there if you don't know what you're doing. 

9 Replies

Hey @JayWilliams,


there is also the option to use some PowerShell code provides by MS for this:

In the PowerShell Intune Samples you have functional scripts for Export/Import of Device Configurations, see here: https://github.com/microsoftgraph/powershell-intune-samples/tree/master/DeviceConfiguration



@Oliver Kieselbach Thanks! I'm sure those work just as well. This was a good opportunity to show the power of using the Graph API.

A benefit for me using this vs PowerShell is not having an environment to maintain. Probably doesn't matter if using Cloud Shell but never hurts to know more than one way to skin the cat. 


This was an excellent intro to Graph - which, to be frank I'd never heard of 30mins ago - now I can copy profiles without any Powershell rabbit holes - but honestly why it isn't in the GUI, we will never know.


Well done and thanks


I agree, it's a simple thing that should be a click away and I'm sure it will be in time. Graph is pretty powerful. As you said, this was just an intro into what you can do with it. There are other tasks that I do in Graph that will probably never be available in GUI, just because there isn't much demand for it so it's a good skill to have in your back-pocket and not have to worry about PS gotchas.

Glad it helped!


@JayWilliams wrote:

Lucky us, the entire Intune UI front end is built using Graph so anything we can do in the UI, we can also do in Graph.


Well, much of it. But not all.
You can do everything you do in UI by automation, but not necessary with Graph API.
Conditional Access is controlled by the API main.iam.ad.ext.azure.com
Haven't found any official documentation for that API, so probably not ment for public usage and possibly unsupported? 


You're right! I totally forgot about that API.
If I remember correctly, I ran across it when trying to do some dynamic group work but didn't spend too much time in there. Thanks for the heads up. I'll edit the post and I'll try to tread lightly in that API.

@JayWilliams Awesome tutorial, this just saved me a ton of time. Like you I work in education and have carts of PCs and I'm onboarding a bunch more and being able to have consistent profile assignments is awesome. On a unrelated note one thing I've done is create a custom logon background for each cart set and applied it so they can find their way home easier, staff really like it. With your help here it made it a piece of cake to make sure it was updated an applied.

I am finding that when I click run query it is not returning all my policies, I also get the same behaviour when I run Get-IntuneDeviceConfigurationPolicy

Any idea why this may be?