Backup and Restore your Microsoft Intune configuration with PowerShell!

Backup and Restore your Microsoft Intune configuration with PowerShell!

6/25/20: BREAKING Update: IntuneBackupAndRestore v2.0.0 released, which relies on the Microsoft.Graph.Intune PowerShell module instead of MSGraphFunctions

Thanks to community feedback and with the version 2.0.0 release of the IntuneBackupAndRestore PowerShell Module, the MSGraphFunctions PowerShell Module is now deprecated and will no longer be maintained by me.

As of version 2.0.0, the IntuneBackupAndRestore PowerShell Module has migrated from the MSGraphFunctions PowerShell module to the Microsoft.Graph.Intune PowerShell module. This allows you to use what’s already there instead of having to maintaining a seperate custom dependency. If you update to the latest version, please make sure you meet the new prerequisites below.

  • Requires Microsoft.Graph.Intune PowerShell Module Install-Module -Name Microsoft.Graph.Intune
  • Connect to Microsoft Graph using the Connect-MSGraph PSCmdlet first.

Do note that the cmdlet to connect with Microsoft Graph is Connect-MSGraph in the Microsoft.Graph.Intune module and not the Connect-Graph cmdlet.

Check out IntuneBackupAndRestore on GitHub for more information.


Original post

Today, I would like to share the release of my
MSGraphFunctions and IntuneBackupAndRestore PowerShell Modules on the PowerShell Gallery with you!

Even more, in this blog post, I will walk you through on how to get started backing up and restoring your Microsoft Intune configuration.

Features

First of all, new features will be added to the IntuneBackupAndRestore module on a regular basis. Be sure to check out what Intune configurations are supported for backup and restore actions on GitHub!

List of features on time of writing this post

Prerequisites

Start by installing the required PowerShell Modules.

Open up a PowerShell prompt (as Administrator) and install the MSGraphFunctions and IntuneBackupAndRestore PowerShell Modules, which I have released on the PowerShell Gallery.

Install-Module -Name MSGraphFunctions
Install-Module -Name IntuneBackupAndRestore

Note: These modules require that you have either the AzureAD or AzureADPreview module installed. Furthermore, the IntuneBackupAndRestore module is dependent on the MSGraphFunctions module.

Now import the modules and you are good to go!

Import-Module -Name MSGraphFunctions
Import-Module -Name IntuneBackupAndRestore

Connect to Microsoft Graph

First of all, the MSGraphFunctions PowerShell Module contains two functions to Connect to Microsoft Graph. One using Delegated permissions (Connect-Graph) and one using Application permissions (Connect-GraphApplication).

Because application permissions are insufficient for the Intune backup & restore actions, we will be using delegated permissions.

Connect-Graph leverages the application ID of the default “Microsoft Intune PowerShell” application in AzureAD by default, so you don’t need to create your own application.

Now, let’s get authenticated with Microsoft Graph!

# Enter the credentials for an Intune Administrator.
$Credential = Get-Credential

# Connect to Microsoft Graph
Connect-Graph -Credential $Credential

If all went well, you will now be successfully connected to Microsoft Graph using delegated permissions!

Backing up Intune configuration

Now that you have connected to Microsoft Graph, it’s time to backup that Intune configuration!

Start-IntuneBackup -Path C:\temp\IntuneBackup

As a result, your Intune configuration will be backed up to json files in the specified path. Looking for the PowerShell Script Content of uploaded scripts? It’s there as well!

Comparing backup files

Before heading on to restoring your Intune configuration from backup, I would like to show you a helper function that identifies changes between backup files.

In this scenario, I have backed up my Intune configuration before making any changes. I then changed a Device Configuration profile, setting some values for the Xbox Service, as shown in the screenshots below.

Old settings
New settings

Now, If I take another backup, I am able to compare the differences between the files using the Compare-IntuneBackupFile cmdlet.

Compare-IntuneBackupFile -ReferenceFilePath $ReferenceFilePath -DifferenceFilePath $DifferenceFilePath
Comparing Intune Backup Files

As you can see in the image above, the previous and current values of the settings are displayed. Also the lastModifiedDateTime and version number of the Device Configuration profile are displayed.

Restoring Intune configuration

For restoring the Intune configuration, there’s a few options you can take.

  1. Restore the full Intune configuration with or without assignments;
    1. For a partial restore, move the json files that you don’t wish to restore to another directory then the given path.
  2. Restore a subset of the Intune configuration using the individual cmdlets.
# Restore Intune configuration
Start-IntuneRestoreConfig -Path C:\temp\IntuneBackup
# If you wish to restore the assignments for Intune configurations
Start-IntuneRestoreAssignments -Path C:\temp\IntuneBackup

Note: Restoring configurations will not overwrite existing configurations, but creates new ones. Restoring assignments may overwrite existing assignments.

Wrapping up!

You can use this PowerShell module to backup an Intune configuration in one tenant and restore it in another tenant. Yet, assignments cannot be restored in another tenant out-of-the-box, as references to Object IDs from Azure AD Groups cannot be translated one to one across tenants.

Finally, if you experience any bugs or have any features requests, feel free to create an issue on the corresponding GitHub projects. I’d be happy to answer any questions on my blog too!

39 thoughts on “Backup and Restore your Microsoft Intune configuration with PowerShell!

  1. Great stuff! We found some configuration profiles in our environment that had / in the name, which the script does not like. Assuming \ would have same issue but have not tested. Luckily not many, so we can adjust on our end – but figured I would pass along the info:

    Backing Up – Device Configuration: iOS – Policy/Test – Non-Standard
    Out-File : Could not find a part of the path ‘C:\users\blah\Documents\Intune\IntuneBackup\Device Configurations\iOS – Policy\Test – Non-Standard.json’.
    At C:\Program
    Files\WindowsPowerShell\Modules\IntuneBackupAndRestore\1.1.0\Public\Invoke-IntuneBackupDeviceConfiguration.ps1:32
    char:49
    + … rtTo-Json | Out-File -FilePath “$path\Device Configurations\$($device …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : OpenError: (:) [Out-File], DirectoryNotFoundException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand

    1. Hi Josh,

      Thanks for using the module and let me know about this issue. Of course, Windows does not accept file names with those characters! I will investigate later and see if I’ll add it as a Known Issue or come up with a workaround to replace invalid characters.

      Regards,

      John

      1. Hello John,
        Do you have a solution for below error ? as you mentioned here , it seems an issue with the long filename with spaces special characters and .
        Out-File : Could not find a part of the path ‘C:\InTuneBackup030921\Device Management Intents\Windows 10 MDM Security Baseline for Decemeber 2020\c04………..-88df6f053f16_Windows 10 MDM Security Baseline for Decemeber
        2020_Windows 10 Security Baseline – Feb 2021_be8…….4-66ffd6193976.json’.
        At C:\Program Files\WindowsPowerShell\Modules\IntuneBackupAndRestore\2.0.0\Public\Invoke-IntuneBackupDeviceManagementIntent.ps1:71 char:47
        + … rtTo-Json | Out-File -LiteralPath “$path\Device Management Intents\$t …
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : OpenError: (:) [Out-File], DirectoryNotFoundException
        + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand

  2. Hi John,

    I am trying to use these scripts however i am running into an issue where the tenant does not seem to have an app name Microsoft Intune Powershell. I get the following exception on line 61 of the Connect-Graph cmdlet:

    System.AggregateException: One or more errors occurred. —> Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException: AADSTS65001: The user or administrator has not consented to use the application with ID ‘d1ddf0e4-d672-4dae-b554-9d5bdfd93547’ named ‘Microsoft Intune PowerShell’. Send an interactive authorization request for this user and resource.

    Although the error seems to imply insufficient permisssions the entire app is unavailable in the tenant I am working with. I checked in a different tenant as well and there the app was not present either.

    Any suggestion on how to work around this? Maybe manually add the app?

    1. Hi Jelle!

      Good question! The “Microsoft Intune PowerShell” application has a “Well-known identifier” that is created automatically by Microsoft. My scripts use non-interactive authentication which does not trigger the application creation, it expects the application to already be present. Might add a switch to force interactive authentication to my MSGraphFunctions module later, to trigger the application creation.

      If the application is missing in your (new) tenant, I’d suggest to install the Intune-PowerShell-SDK (Install-Module -Name Microsoft.Graph.Intune) and connect to Microsoft Graph once with the “Connect-MSGraph -AdminConsent” cmdlet. I believe this is one of several ways to trigger the creation of the Enterprise Application.

      Please let me know if the solution provided is working for you!

        1. You’re welcome! FYI: I have also updated the MSGraphFunctions module now to support the automated creation of the “Microsoft Intune PowerShell” Enterprise Application and added support for accounts with Multi-Factor Auth enabled by default!

  3. I got this error message:
    Connect-Graph : Authorization Access Token is null, please re-run authentication…
    At line:4 char:1
    + Connect-Graph -Credential $Credential
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Connect-Graph

  4. Hi, I’m getting this error when execute Start-IntuneRestoreAssignments (The configurations are restoring fine):

    MacOS Test – Successfully restored Device Compliance Policy Android Enterprise – Test – Successfully restored Device Configuration
    Invoke-IntuneRestoreGroupPolicyAssignment : The term ‘Invoke-IntuneRestoreGroupPolicyAssignment’ is not recognized as
    the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
    included, verify that the path is correct and try again.
    At C:\Program
    Files\WindowsPowerShell\Modules\IntuneBackupAndRestore\1.3.1\Public\Start-IntuneRestoreAssignments.ps1:36 char:5
    + Invoke-IntuneRestoreGroupPolicyAssignment -Path $path -RestoreByI …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (Invoke-IntuneRe…olicyAssignment:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    1. Hi Jean,

      Thank you for reporting the issue. I have been able to reproduce and fix the issue in the v1.3.2 release of the IntuneBackupAndRestore PowerShell Module (Update-Module -Name IntuneBackupAndRestore).

      I’d be happy to hear if the issue is resolved for you.

      Regards,

      John

  5. Hello Jean
    thank you for the great script it works ,-) I have a question is it also possible to save / restore Home
    Deployment profiles? located here?

    Microsoft Intune->
    ->Device enrollment – Windows enrollment
    ->Windows Autopilot deployment profiles

    thx a lot
    Marcel

  6. Hi John,

    I’m stuck right at the first part. The modules install correctly but I cannot call Connect-Graph it just says it is not recognized as the name of a cmdlet.

    Can you help?

    1. Hi Joshua,

      After installing the PowerShell Module you may need to import it with Import-Module MSGraphFunctions cmdlet.

      When the PowerShell Module is imported in your PowerShell session, you should be able to run the Connect-Graph cmdlet.

      Regards,

      John

  7. Hi John,
    i have a question regarding permission that i hope you could answer.
    when using Delegated permissions to connect to Microsoft Graph, what is the minimum rights a user needs for doing the backup and restore.
    the reason im asking, is because i thinking of setting up services account that will run on a task scheduler.

    1. Hi Jacko,

      Depending on what items you want to backup or restore require different permissions. I’d suggest to assign the “Intune administrators” directory role for a service account. You can add a custom Intune RBAC role, know that it will need to permissions for the items that you are trying to backup or restore.

      Regards,

      John

  8. Hi,

    Thanks for this it works great for me but I’m trying to get it running under a service account for a scheduled task. What rights do I need to give the account for it to work?
    Getting this after giving the account intune admin rights

    Successfully connected to Microsoft Graph! (Tenant ID: 856f90cd-2278-4194-82cd-f13fab22965a)
    Get-GraphClientApp : Request to https://graph.microsoft.com/beta/deviceAppManagement/mobileApps?$top=999 failed with HTTP Status Unauthorized Unauthorized.
    Response content:
    {
    “error”: {
    “code”: “UnknownError”,
    “message”: “{\”ErrorCode\”:\”Forbidden\”,\”Message\”:\”{\\r\\n \\\”_version\\\”: 3,\\r\\n \\\”Message\\\”: \\\”An error has occurred – Operation ID (for customer
    support): 00000000-0000-0000-0000-000000000000 – Activity ID: b1a7fac2-d74f-455b-85f8-d08a9176e706 – Url:
    https://fef.msub03.manage.microsoft.com/AppLifecycle/StatelessAppMetadataFEService/deviceAppManagement/mobileApps?api-version=5019-05-23&$top=999\\\”,\\r\\n
    \\\”CustomApiErrorPhrase\\\”: \\\”\\\”,\\r\\n \\\”RetryAfter\\\”: null,\\r\\n \\\”ErrorSourceService\\\”: \\\”\\\”,\\r\\n \\\”HttpHeaders\\\”:
    \\\”{\\\\\\\”WWW-Authenticate\\\\\\\”:\\\\\\\”Bearer realm=\\\\\\\\\\\\\\\”urn:intune:service,9225b241-44e1-44a8-8bfe-c10e39177505,f0f3c450-59bf-4f0d-b1b2-0ef84ddfe3c7\\
    \\\\\\\\\\\\\”\\\\\\\”}\\\”\\r\\n}\”,\”Target\”:null,\”Details\”:null,\”InnerError\”:null,\”InstanceAnnotations\”:[]}”,
    “innerError”: {
    “request-id”: “b1a7fac2-d74f-455b-85f8-d08a9176e706”,
    “date”: “2019-07-12T09:46:48”
    }
    }
    }
    At C:\Program Files\WindowsPowerShell\Modules\IntuneBackupAndRestore\1.3.2\Public\Invoke-IntuneBackupClientAppAssignment.ps1:28 char:19
    + $clientApps = Get-GraphClientApp
    + ~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-GraphClientApp

    1. Hi Michael,

      Not sure where it went wrong there. I just created a test user and added it the the “Intune administrators” directory role, and was successfully able to run the Get-GraphClientApp cmdlet. There are some docs that users with this role or RBAC roles require a license, though.

      Regards,

      John

  9. Hi,

    Nice work on these backup scripts. For the most part they are working but I do get a couple of errors. Any help would be much appreciated
    ————–
    Admin Templates – Failed to restore Group Policy Configuration and/or (one or more) Settings
    Invoke-IntuneRestoreGroupPolicyConfiguration : Request to https://graph.microsoft.com/beta/deviceManagement/groupPolicy
    Configurations/401596c9-5608-4646-bc90-3ac0ba808bbc/definitionValues failed with HTTP Status BadRequest Bad Request.
    Response content:
    {
    “error”: {
    “code”: “ModelValidationFailure”,
    “message”: “The property ‘value’ does not exist on type
    ‘microsoft.management.services.api.groupPolicyPresentationValueList’. Make sure to only use property names that are
    defined by the type.”,
    “innerError”: {
    “message”: “The property ‘value’ does not exist on type
    ‘microsoft.management.services.api.groupPolicyPresentationValueList’. Make sure to only use property names that are
    defined by the type.”,
    “request-id”: “9406a9e7-ec64-46d9-994d-5f95225c43bb”,
    “date”: “2019-07-23T07:04:11”
    }
    }
    }
    At C:\Program Files\WindowsPowerShell\Modules\IntuneBackupAndRestore\1.4.2\Public\Start-IntuneRestoreConfig.ps1:30
    char:5
    + Invoke-IntuneRestoreGroupPolicyConfiguration -Path $Path
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Invoke-IntuneRestoreGroupPolicyConfigu
    ration

    And —————————

    Kiosk – Failed to restore Device Configuration
    Invoke-IntuneRestoreDeviceConfiguration : Request to
    https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations failed with HTTP Status BadRequest Bad Request.
    Response content:
    {
    “error”: {
    “code”: “BadRequest”,
    “message”: “Property appConfiguration in payload has a value that does not match schema.”,
    “innerError”: {
    “request-id”: “f83cbb88-6075-4a7b-a7ac-9b3714b74372”,
    “date”: “2019-07-23T07:04:02”
    }
    }
    }
    At C:\Program Files\WindowsPowerShell\Modules\IntuneBackupAndRestore\1.4.2\Public\Start-IntuneRestoreConfig.ps1:28
    char:5
    + Invoke-IntuneRestoreDeviceConfiguration -Path $Path
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Invoke-IntuneRestoreDeviceConfiguratio
    n

    1. Hi Cliff,

      Sorry for the late reply! Would you be able to share the json config that you are trying to restore? I’d love to look into the source files that generate the errors and fix the module appropriately!

      Regards,

      John

  10. Any plans to backup AutoPilot data? Currently MSFT does not have an option to export or backup the Serial, Windows Product ID, Hardware Hash values.

    1. Hi Niles,

      Thanks for your comment! Your feature request is noted but no (short-term) plans at this time. However, the Microsoft Graph API offers no support to extract imported hardware hash values using the Microsoft Graph API at this time.

      There is some Autopilot information available though, such as the Serial number, Manufacturer and Model, which can be used by CSPs to import devices through the Partner Center.

      Regards,

      John

  11. been doing this several times and worked great, however now i get this error :(?

    I don’t know what changed, i didn’t make any changes to my setup.

    PS C:\WINDOWS\system32> connect-msgraph

    UPN TenantId
    — ——–
    admin@partsunlimited1.onmicrosoft.com a2e90888-672f-4ad8-877d-023cbd41a40b

    PS C:\WINDOWS\system32> Start-IntuneBackup -path C:\temp\Backup
    Get-GraphClientApp : Request to https://graph.microsoft.com/beta/deviceAppManagement/mobileApps?$top=999 failed with HT
    TP Status Unauthorized Unauthorized.
    Response content:
    {
    “error”: {
    “code”: “InvalidAuthenticationToken”,
    “message”: “Access token is empty.”,
    “innerError”: {
    “request-id”: “0a98f123-4d3c-4436-aedd-c052ab1b818b”,
    “date”: “2019-11-20T14:48:08”
    }
    }
    }
    At C:\Program Files\WindowsPowerShell\Modules\IntuneBackupAndRestore\1.4.2\Public\Invoke-IntuneBackupClientApp.ps1:28 c
    har:19
    + $clientApps = Get-GraphClientApp
    + ~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-GraphClientApp

    1. Hi Jonas,

      Connect-MSGraph refers to a different PowerShell Module (Intune PowerShell SDK) then the one used in thuis guide (MSGraphFunctions > Connect-Graph).

      Best regards,

      John

  12. Hi,

    Doesnt Microsoft have automatic Backup and Recovery feature for Intune services ? or this is the recommended way by Microsoft ?

    1. Hi Sufi,

      They probably do for their own services.

      However, this module can help you to revert to a point-in-time configuration, track changes between multiple backup sets or even backup and restore configurations cross-tenant.

      This is a 3rd party solution that is in no way affiliated with Microsoft.

      Best regards,

      John

  13. This worked flawlessly for me to backup config policies from one tenant and import them to another tenant. I am now trying to find and or figure out a way to do this same type of task for client apps and autopilot profiles. Any thoughts and or suggestions would be greatly appreciated as that would almost fully automate this for me when spinning up new tenants. Thank you!

    1. Hi Nathan,

      That’s great to hear!

      The PowerShell module does not support exporting and importing Client Apps and Autopilot Profiles (at this time).

      Best regards,

      John

  14. I’m running into a problem with the Connect-Graph cmdlet. My tenant is requiring modern authentication with MFA, and the connect-graph doesn’t seem to support. I’ve tried installing and running using the Exchange Online Powershell Module which does support the MFA interface, but still get the same issue:
    connect-graph: cannot find an overload for “AcquireTokenAsync” and the argument count: 5

  15. Is there an option to only backup specific items in the same way as they can be restored? This would be really useful to create before and after images for changes without having to dump the entire Intune config which can take time
    Thanks

    Neil

  16. Fantastic Job!
    I have been using commands from the powershell intune Gallery.
    Ran jus fine for me. The only question I have as I review the exported content is I cannot fond the JSon for the App Config for the Managed Devices. The Managed App configs are under the App Protection policies folder. However I cannot find the Managed Device app configs anywhere.

Leave a Reply

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