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.
