How to easily backup your Intune environment using IntuneCD and Azure DevOps Pipeline

How to easily backup your Intune environment using IntuneCD and Azure DevOps Pipeline

IntuneCD + GIT repository + Pipeline + Intune Audit Log = Intune configuration backup solution where even who made the change is back-upped

ยท

10 min read

Play this article

I was quite surprised when I found out how easy is to regularly back up your Intune environment configuration using the great IntuneCD tool and Azure DevOps service.

Today I will show you how I took the existing solution and improved it so that even the author of the Intune configuration change is included in the backup.

The result?

You can easily browse through your Intune environment history saved in your GIT repository and see who made what change and when it happened ๐Ÿคฏ


Main benefits of this solution

  • it is free of charge

  • all your Intune configuration will be regularly backed up to your private Azure DevOps GIT repository

  • visibility to Intune changes made during the time including the author of such change

  • ability to see how the Intune was configured at a specified point in time

  • runs in Azure DevOps Pipeline a.k.a. purely code-driven & cloud-driven (no on-premises requirements whatsoever)


Requirements

  • Microsoft account to be able to log in to Azure DevOps service

  • permission to

    • create Azure application

    • grant the application required Graph API permissions


Let's do this!

This solution needs: one Azure Service Principal, GIT repository (hosted in Azure DevOps), and Pipeline.

Azure application

Create Azure application

This application (IT_Intune_Backupper in my case) will be used to authenticate to Graph API a.k.a. to gather Intune configuration data.

When created, make a note of its Application ID (3f3944e3-ed3d-46f5-b487-89b95f1e2e80 in my case). This value will be used later in the DevOps pipeline.

And grant the created application the following Graph API application permissions:

๐Ÿ’ก
Don't forget to Grant admin consent for all those permissions too!

All permissions except DeviceManagementConfiguration.ReadWrite.All grant READ-only access. DeviceManagementConfiguration needs ReadWrite unfortunately otherwise backup fails with forbidden error.

Create application secret

Create a new application secret (password). It will be used in the DevOps pipeline for authentication later.

Azure DevOps repository

Create a private Azure DevOps repository

Go to https://dev.azure.com/ and create a PRIVATE new GIT repository (project).

Assign contribute permission

Go to Project settings > Repositories > Security and grant Contribute 'ALLOW' permission to Build Service account. Otherwise, pipeline jobs will fail when a commit is made.

Azure DevOps repository pipeline

The pipeline is where all magic happens. It is in fact script that defines what should happen during the pipeline run.

Create new Pipeline

  • To be able to create a pipeline, your repository needs to be initiated first.

    • Go to Repos > Files > choose Initialize

  • Now go to Pipelines and create the pipeline using Create Pipeline button

  • Select Azure Repos Git

  • Select Starter pipeline

If you want to create

  • Markdown document describing your Intune environment, uncomment Task Generate markdown document & commit

  • PDF and HTML documentation reports as artifacts, uncomment also whole PUBLISH job

By default this pipeline will be started every day at 1 am. If you want to change that, just alter the cron key value (cron: '0 1 * * *'). You can use https://crontab.guru to generate a new one.

Customize predefined pipeline variables

At the beginning of the pipeline code, there are some variables defined that need to be set to suit your environment.

  • TENANT_NAME

  • USER_EMAIL

    • you can leave it as it is

    • default email that will be used as commits author email, something like (or whatever you wish)

  • USER_NAME

    • you can leave it as it is

    • default username that will be used as commits author, something like Intune_Backupper (or whatever you wish)

Create required pipeline variables

Two pipeline variables need to be set outside the pipeline code (because of security).

Use the Variables button in the right top corner to create them.

  • CLIENT_ID

    • Enter the Application ID mentioned earlier (3f3944e3-ed3d-46f5-b487-89b95f1e2e80 in my case)
  • CLIENT_SECRET

    • Enter the Application secret mentioned earlier. Don't forget to checkKeep this value secret!

    • Secret has a limited lifetime, hence you will need to update this value with every secret refresh!

And the final result should look similar to this ๐Ÿ‘‡

Save & Run the pipeline

Now when the pipeline is ready, save it choosing Save and run . This way you will immediately see whether the pipeline is working fine ๐Ÿ‘

After pipeline finishes, you should see that prod-backup folder was created and is filled with your Intune configuration JSON files ๐Ÿ˜

According to the schedule, it will be automatically started by default every day at 1 a.m.

What does this pipeline do?

  • Install IntuneCD tool

  • Export Intune configuration backup to prod-backup folder

  • If a change in configuration is detected

    • For each changed file find who did it

      • by searching the Intune Audit log for particular ResourceId changes since the last config commit date
    • Group changed files by author(s) who changed them

    • Commit each group separately by using the author name(s) as the commit author(s) too

    • Create an Intune configuration documentation file (as markdown)

      • (only if you uncomment the task Generate markdown document & commit)
    • Create Git TAG

      • name of all changes authors will be included in the TAG description
    • Generate HTML and PDF files from the Intune configuration documentation file and save them as Pipeline Artifacts

      • (only if you uncomment task Generate markdown document & commit, job Publish as-built artifacts and add the folder md2pdf (from this repository) to your repository root)
  • If there is no change

    • Pipeline ends

By default you have 1800 minutes of pipeline run per month for free. One Intune backup pipeline run takes approximately 2 minutes from this pool, so no problem here.


Send a notification in case the pipeline fails

It is useful to be notified when the pipeline fails. For example because application secret expired etc. To do so go to Project settings > Notifications > New Subscription and select Build > A Build fails end finish the wizard.


How to

Because backup is saved in the GIT repository, you can use commands you are familiar with (git log, git diff, git blame, etc) and don't be limited to GUI as shown below.

Get changes made to the specific file

To get a list of all changes to the particular file. Open such file in the DevOps interface and choose History tab.

To see what has changed between two commits/conf. backups. Choose Compare tab.

Get changes made by a specific author

Because change author name is used as commit author and in commit name itself, you can search it by several ways. In DevOps gui, you can switch to Commits > Click on Show filter button in top right corner

And type author's name to Author field.

In GIT, you can use git log command to achieve the same

Get changes made between specified dates

To get a visual list of changes made in your Intune configuration between specified dates, go to Repos > Tags select the first Tag and Set as compare tag, then select the second one and run the comparison by Compare tags

On the result page select Files and enjoy the view ๐Ÿ™‚

Strikethrough files are settings that were deleted. Plus sign on the right side of the file means it is a new setting that was created.

Show the Intune configuration status on a specific date

To see what your Intune environment looked like on a specific date. Go to Repos > Tags > Pick the nearest olderTag > Open the folder prod-backup and browse the content (exported JSON configuration files).

This way you will see how your Intune looked like just before the specified date.

To see what changes were made during this time, compare thisTag with the nearest newerTag.

Beware that if someone made some changes in the configuration and reverted them back before the next backup occurred, they won't be shown (obviously).

Change what should be included in the backup

To modify what type of Intune configurations should be backed up, you must edit Create Intune backup task section in the Pipeline configuration code.

Go to Pipelines > <yourPipeline> > click Edit > Find a task with the name Create Intune backup and modify its script section by modifying the --exclude parameter.

By default, I am excluding CompliancePartner, because its data changes every day and I want new commits to be created only in case some real change happens.

Restore the backup

When restoring the backup, you have basically two options.

  1. Use the IntuneCD update feature

    1. create new folder

    2. copy just folder structure with JSON(s) you want to restore to this folder

    3. run IntuneCD-startupdate with --path "pathToFolderWithBackup"

  2. Manually create the required Intune configuration(s) by filling in the values shown in your backup JSON(s)


How the change author(s) are managed

In the GIT repository, if you want to see who changed file XYZ, you check who was the author of the commit that changed such file. Therefore it was only logical to use the same approach to "save" information about who has changed the Intune configuration (JSON file).

How the change author is found?

When change is detected in the created backup (some JSON configuration file is changed) the pipeline will

  • Get a list of all changed files

  • Getting the last configuration backup commit date ($lastCommitDate)

    • if no commit exists whole Intune Audit log will be searched
  • For each changed file find out who changed it by

    • retrieving resource ID from its name

    • searching such ID in the Intune Audit log (between dates saved in $lastCommitDate and start time of this backup run) and making note of all authors that made some changes there

  • Group the changed files by found authors and make a commit for each group where the list of all authors that changed such files is used in the commit name and as the commit author

  • Put all found authors into Git Tag description too

Good to know

  • The list of author(s) doesn't have to be 100% accurate. If you need 100% accuracy (because of security incident etc), use the command Get-MgDeviceManagementAuditEvent

    • for example when someone makes a change in the Intune right after the backup starts. Such change can be captured, but the author will not, because the Intune log is searched from the last commit date to the start of the backup task only. If the search ended at the backup finish instead, it could lead to an opposite situation when the author list could contain someone who didn't make the change that was captured in the backup.
  • The list of commit authors shows who has made any changes to committed files (since the last commit). It doesn't show who made what particular change

  • If a change was made by an application (instead of a user), the name of the application is used as the author name with (SP) suffix (for example Modern Workplace Management (SP))

  • Some Intune configuration changes aren't captured in the Intune Audit log at all! Like changes to ESP profile etc.

    • Therefore if the author of the changed configuration wasn't found in the Audit log, unknown is used instead
  • Intune uses several formats of IDs! Not just <GUID> as you would imagine, but for example ESP profile, Apple configurator profile , App Protection policy uses <GUID>_<GUID>, <GUID>_<somestring>,T_<GUID> and there are probably some other crazy stuff


Summary

If you finished all the required steps, you now have a working backup solution for your Intune configuration which you can easily use for tracking changes & blame the change authors ๐Ÿ˜Ž

Next time I will show you have to achieve the same thing for Azure configuration as well ๐Ÿ‘


Links

Did you find this article valuable?

Support Ondrej Sebela by becoming a sponsor. Any amount is appreciated!

ย