Intune Backup and Restore via Automation account in Azure

Good afternoon,

In the past, I have been using this extremely useful script from the PowerShell gallery to backup Intune configuration manually. PowerShell Gallery | IntuneBackupAndRestore 4.0.0. Im trying to automate this and write to a blob storage container. All this is ran within a “RunBook” inside the automation account. I will admit that I have had to lean in AI to inspect script and it and clean it up.

I have imported the modules below, and now starting to trying and execute the script I cant get it to connect to either a registered app, managed Identity with API permissions or an automation account and I have fallen into a bit of a rabbit hole.

Microsoft.Graph.Authentication
Microsoft.Graph.DeviceManagement
Microsoft.Graph.DeviceManagement.Configuration
Microsoft.Graph.DeviceManagement.ManagedDevices
Microsoft.Graph.DeviceManagement.Enrollment
Microsoft.Graph.Groups
Microsoft.Graph.Users
Microsoft.Graph.Identity.DirectoryManagement
IntuneBackupAndRestore

I have verified that the automation account has access to Graph API by adding roles to the following :

# =========================
# CONFIG 
# =========================
$TenantId           = "My-Tenant-ID"   # Entra tenant
# SAMI on the Automation Account will be used automatically (no ClientId needed)

$StorageAccountName = "saintune"
$ContainerName      = "backup"

$BackupNamePrefix   = "IntuneBackup"
$BackupPath         = "C:\temp\IntuneBackup"                   # per your command
$Timestamp          = (Get-Date).ToString("yyyyMMdd-HHmmss")
$BlobPrefix         = "$BackupNamePrefix-$Timestamp"           # virtual folder in Blob

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

# =========================
# STEP 0: Import modules (no Microsoft.Graph roll-up)
# =========================
$graphModules = @(
  'Microsoft.Graph.Authentication',
  'Microsoft.Graph.DeviceManagement',
  'Microsoft.Graph.DeviceManagement.Configuration',
  'Microsoft.Graph.DeviceManagement.ManagedDevices',
  'Microsoft.Graph.DeviceManagement.Enrollment',
  'Microsoft.Graph.Groups',
  'Microsoft.Graph.Users',
  'Microsoft.Graph.Identity.DirectoryManagement'
)
$otherModules = @('Az.Accounts','Az.Storage','IntuneBackupAndRestore')

$missing = New-Object System.Collections.Generic.List[string]
foreach ($m in ($graphModules + $otherModules)) {
  try { Import-Module $m -ErrorAction Stop } catch { $missing.Add($m) | Out-Null }
}
if ($missing.Count -gt 0) {
  throw "Missing modules in this Automation Account: $($missing -join ', '). Add them under Automation Account → Modules (Browse gallery) and rerun."
}

# =========================
# STEP 1: Connect to Microsoft Graph via System-Assigned MI
# =========================
Write-Output "Connecting to Microsoft Graph with System-Assigned Managed Identity..."
Connect-MgGraph -Identity -TenantId $TenantId -NoWelcome | Out-Null
$mg = Get-MgContext
if (-not $mg -or -not $mg.TenantId) { throw "Graph authentication failed. Ensure SAMI has Graph app permissions with admin consent." }
Write-Output "Connected to Graph. Tenant: $($mg.TenantId)."

# =========================
# STEP 2: Prepare backup path
# =========================
if (-not (Test-Path -LiteralPath $BackupPath)) {
  New-Item -ItemType Directory -Path $BackupPath -Force | Out-Null
}

# Optional: clear previous contents (comment out if you want to keep)
# Get-ChildItem -Path $BackupPath -Recurse -Force | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue

# =========================
# STEP 3: Run Intune backup
# =========================
Write-Output "Starting Intune backup to $BackupPath ..."
# Minimal call (no zip). If your module supports -IncludeAssignments, you can add it later.
Start-IntuneBackup -Path $BackupPath -Verbose

# =========================
# STEP 4: Upload to Azure Storage using SAMI (no zip)
# =========================
Write-Output "Authenticating to Azure with System-Assigned Managed Identity..."
Connect-AzAccount -Identity -Tenant $TenantId | Out-Null

$ctx = New-AzStorageContext -StorageAccountName $StorageAccountName -UseConnectedAccount

# Ensure container exists (private)
$container = Get-AzStorageContainer -Name $ContainerName -Context $ctx -ErrorAction SilentlyContinue
if (-not $container) {
  Write-Output "Creating container '$ContainerName' ..."
  $null = New-AzStorageContainer -Name $ContainerName -Context $ctx -Permission Off
}

Write-Output "Uploading files from $BackupPath under virtual folder '$BlobPrefix/' ..."
Get-ChildItem -Path $BackupPath -Recurse -File | ForEach-Object {
  $rel = $_.FullName.Substring($BackupPath.Length).TrimStart('\','/')
  $blobName = "$BlobPrefix/$($rel -replace '\\','/')"
  Set-AzStorageBlobContent -File $_.FullName -Container $ContainerName -Blob $blobName -Context $ctx -Force | Out-Null
  Write-Output "Uploaded: $blobName"
}

Write-Output "Done. Backup root:"
Write-Output ("https://{0}.blob.core.windows.net/{1}/{2}/" -f $StorageAccountName, $ContainerName, $BlobPrefix)

When the script it fails advising that the modules missing even though they are all imported.

I’m really lost now.

Please may I ask for some help with this.

Hi, welcome to the forum :wave:

Why do you say that the modules are all imported? If the script is reporting that the modules are missing, then based on the code you’ve provided, at least one of the modules is creating an error during import, otherwise the error would not be thrown.

I would start by modifying the catch block for the Import-Module section so that as well as (or instead of) adding the failing modules to an array, you can see why importing them is failing.

any chance we can see the error code?

Hi Matt,

Firstly, thank you for a warm welcome and a swift reply. Please allow me to provide some more context, as my account will not allow multiple pictures so I had to join the images together to post it, sorry its a but sketchy

1.The modules are imported into the automation account from the PowerShell gallery.

2.The PowerShell environment is controlled by the runbook further up the left hand panel

3.The code is pasted into the the runbook from here

4.I have added the cmdlet import-module and the error has gone from the results page and now hangs on the parameter issue

Thank you

Connect-MgGraph -Identity -TenantId $TenantId -NoWelcome | Out-Null

The error is occuring because that isn’t valid syntax for the Connect-MgGraph command. The correct syntax will depend on how you want to authenticate.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.