Enable Update Management for Azure VM (ARM Template + PowerShell)

A few months back I started a new journey with a new employer. In my organization, they do e-commerce hosting for various customers all over the world. So when the customer needs to host our e-commerce product as a hosting team it’s our responsibility to create the relevant Azure cloud infrastructure that needs for the application. To complete this task we have an automated script that does entier deployment from the creation of Azure resources and DSC of Windows Servers. Until recently the script enables the full windows update for each VMs and its not leveraging Azure Update Management feature.

Problem Statement

If you enable all the update types ( Update rollups, Feature packs, etc) the update will take a long time to complete and some update may effect to break the application.


So the solution for this is to automate the update deployment on a specific date and schedule the process through Azure Update Management. With Azure Update Management it streamlines the update process and gets a better insight of updates.

Bellow Resources should deploy when we adding Azure Update Management.

  • PowerShell script to deploy ARM Template, create a schedule for update
  • ARM template for deploy VM and parameter file

Next, I’ll break down the process of implementing Azure Update Management.

ARM Template

For this I used a basic ARM template for the deployment of VMs, In addition, I added additional modifications as mentioned below.

VM Extensions

The following extension was added to the VMs.

  • Microsoft.Azure.Diagnostics – This extension used to gather VM diagnostics data for troubleshooting when VM is unaccessible
  • Microsoft.EnterpriseCloud.Monitoring – This extension provisioned the monitoring agent for the VM. For update management, we have to provide the monitoring agent to gather update status of the VM

Log Analytics Workspace & Automation Account

Following JSON used to create a Log Analytics Workspace to store log data from multiple connected services. Automation account connected to Log Analytics Workspace using Microsoft.OperationalInsights/workspaces/linkedServices

Following is the complete ARM Template.

Next, we need to deploy the ARM template and create a schedule update for the VMs.

Below PowerShell commands are used to create Resource Group in Azure and deploy VM, Log Analytics Workspace, Automation Account etc.

#Create Resource Group
$ResourceGroup = (New-AzResourceGroup -Name VM-UpdateMgt -Location "Southeast Asia").ResourceGroupName

#Create ARM Deployment
New-AzResourceGroupDeployment -Name VM-UpdateMgt -ResourceGroupName $ResourceGroup -Mode Incremental -TemplateFile ./azuredeploy.json -TemplateParameterFile ./azuredeploy-parm.json -Verbose

After ARM template deployment succeeded, next is to create an updated schedule for the VMs.

#Configure Update Management

$duration = New-TimeSpan -Hours 2
$StartTime = (Get-Date "02:00:00").AddDays(5)
$ImediateUpdateStartTime = (Get-Date).AddHours(1)
[System.DayOfWeek[]]$WeekendDay = [System.DayOfWeek]::Sunday
$AutomationAccountName = (Get-AzAutomationAccount -ResourceGroupName $ResourceGroup).AutomationAccountName 
$LogAnalyticsWorkspaceName = (Get-AzOperationalInsightsWorkspace -ResourceGroupName $ResourceGroup).Name

Write-Host "Wait Until VM Extensions are enabled"
Start-Sleep -Seconds 180

Above variable are useful for update schedule, therefore we stored it as variables and reuse them on below PowerShell commands.

The next step is to create a weekly and onetime update scheduler for VMs. Following PowerShell create scheduler for update management.

#Create a Weekly Scedule 
$Schedule = New-AzAutomationSchedule -AutomationAccountName $AutomationAccountName -Name "WeeklyCriticalSecurity" -StartTime $StartTime -WeekInterval 1 -DaysOfWeek $WeekendDay -ResourceGroupName $ResourceGroup -Verbose
#Imediate Update Scedule
$ImediateUpdateSchedule = New-AzAutomationSchedule -AutomationAccountName $AutomationAccountName -Name "FullUpdate" -StartTime $ImediateUpdateStartTime -OneTime -ResourceGroupName $ResourceGroup -Verbose

#Get VM IDs
$VMIDs = (Get-AzVM -ResourceGroupName $ResourceGroup).Id 

Next, we will take the VM Ids and configure Azure Automation configuration for weekly and one time updates.

#Software Update Weekly configuration
New-AzAutomationSoftwareUpdateConfiguration -ResourceGroupName $ResourceGroup -Schedule $Schedule -Windows -AzureVMResourceId $VMIDs -Duration $duration -IncludedUpdateClassification Critical,Security,Definition -AutomationAccountName $AutomationAccountName -Verbose

#Software Update Onetime configuration
New-AzAutomationSoftwareUpdateConfiguration -ResourceGroupName $ResourceGroup -Schedule $ImediateUpdateSchedule -Windows -AzureVMResourceId $VMIDs -Duration $duration -IncludedUpdateClassification Critical,Security,ServicePack,FeaturePack,UpdateRollup,Updates,Definition -AutomationAccountName $AutomationAccountName -Verbose

Following is the complete deployment script.