Application Management and Patching
How to Deploy a Runbook to Monitor Intune App‑Installation Errors
As we showed in the recent Recast Automation webinar, an Azure Automation runbook makes it simple to build proactive alerts for Intune. In this blog post, I’ll show you step-by-step how to deploy a script into Azure Automation.
Prerequisites
Before we begin, make sure you have:
- An Azure subscription with permissions to create Automation Accounts.
- The Monitor-IntuneAppInstallationErrors.ps1 script (see below).
Create Automation Account and Enable Managed Identity
For detailed steps on creating an Automation Account, see my earlier post.
Here’s the short version:
- Search for “Automation Accounts” in the Azure Portal.
- Click + Create, choose your Subscription and Resource Group, give it a name (e.g. intune-automation), and pick a Region.
- In the Identity tab, toggle System‑assigned managed identity to On, then select Save.
You can deploy the same resources with Terraform; I’ll cover that in an upcoming post.
Import Required Modules
Under your new Automation Account:
- Navigate to Modules > + Add a module.
- Select PowerShell Gallery.
- Search for and install:
- Az.Accounts
- Az.Resources
- Microsoft.Graph.Authentication
- Microsoft.Graph.Mail
These modules enable managed‑identity sign‑in and Microsoft Graph API calls.

Configure Automation Variables
I store the script parameters in Terraform so thresholds and email settings can be changed without editing code; you can also add the variables manually in the Automation Account.
This is my Terraform template:
resource "azurerm_automation_variable_int" "error_threshold" {
name = "ErrorThreshold"
resource_group_name = azurerm_resource_group.rg.name
automation_account_name = azurerm_automation_account.automation.name
value = "10"
}
resource "azurerm_automation_variable_int" "days_back" {
name = "DaysBack"
resource_group_name = azurerm_resource_group.rg.name
automation_account_name = azurerm_automation_account.automation.name
value = "7"
}
resource "azurerm_automation_variable_string" "sender_email" {
name = "SenderEmail"
resource_group_name = azurerm_resource_group.rg.name
automation_account_name = azurerm_automation_account.automation.name
value = "noreply@contoso.com"
}
resource "azurerm_automation_variable_string" "recipient_email" {
name = "RecipientEmail"
resource_group_name = azurerm_resource_group.rg.name
automation_account_name = azurerm_automation_account.automation.name
value = "it-ops@contoso.com"
}
This is how you can add them via the portal:

Import, Publish, and Link the Runbook
- In Runbooks, select + Create a runbook.
- Enter:
- Name: Monitor-IntuneAppInstallationErrors
- Runbook type: PowerShell
- Runtime: 7.2
- Choose Edit, paste in the full contents of Monitor‑IntuneAppInstallationErrors.ps1 (shown below), and select Save.
- Click Publish to make it available.
# ==============================================
# Monitor-IntuneAppInstallationErrors.ps1
# ==============================================
try {
$ErrorThreshold = Get-AutomationVariable -Name "ErrorThreshold" -ErrorAction Stop
} catch {
$ErrorThreshold = 10
}
try {
$DaysBack = Get-AutomationVariable -Name "DaysBack" -ErrorAction Stop
} catch {
$DaysBack = 7
}
Connect-AzAccount -Identity -ErrorAction Stop
$token = (Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com").Token
$hdr = @{ Authorization = "Bearer $token"; "Content-Type" = "application/json" }
# Email variables
try { $senderEmail = Get-AutomationVariable -Name "SenderEmail" } catch { $null }
try { $recipientEmail = Get-AutomationVariable -Name "RecipientEmail" } catch { $null }
$end = Get-Date
$start = $end.AddDays(-$DaysBack)
# Build request
$requestBody = @{
top = 50; skip = 0;
select = @("DisplayName","Publisher","Platform","AppVersion","FailedDevicePercentage","FailedDeviceCount","InstalledDeviceCount");
orderBy = @("FailedDevicePercentage desc")
} | ConvertTo-Json -Depth 3
$response = Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/reports/getAppsInstallSummaryReport" `
-Method POST -Headers $hdr -Body $requestBody
# Process rows into objects
$report = $allApps | Where-Object { $_.ErrorRate -ge $ErrorThreshold } | Sort ErrorRate -Descending
$top5 = $allApps | Sort InstalledCount -Descending | Select -First 5
# Build HTML & send email if configured
if ($senderEmail -and $recipientEmail) {
# Construct $html and $subject based on $report.Count…
Invoke-RestMethod -Method POST -Uri "https://graph.microsoft.com/v1.0/users/$senderEmail/sendMail" `
-Headers $hdr -Body ($BodyJsonsend) -ContentType "application/json"
}
Schedule and Test the Runbook
- Back in Runbook, select Start in the Test pane to verify that it runs successfully. Review the output for any errors or warnings.
- When the test succeeds, open Schedules > + Add a schedule.
- Create a new schedule:
- Name: Daily-IntuneAppErrorCheck
- Recurrence: Daily, every 1 day, at 07:00 AM (your local).
- Link the schedule to the runbook.
Verify Alerts and Logs
- Open Jobs under the runbook to review past runs, exit codes, and output.
- If errors exceed the threshold, you should receive an email from your configured sender to the recipient.
- Fine‑tune the ErrorThreshold or DaysBack variables in Terraform, then re‑apply the configuration as needed.
Conclusion: Runbook to Monitor Intune App‑Installation Errors Deployed
Congratulations! You now have a fully automated monitoring solution for Intune app‑installation errors built with Azure Automation runbooks, Terraform‑managed configuration, and Microsoft Graph API calls—all building on what we covered in the Recast Automation webinar.