How to Automate Daily System State Backups for Windows Azure VMs Using PowerShell


4 views

When working with Windows Azure Virtual Machines, many administrators face a common dilemma - while Azure Backup handles data protection well, system state backups require additional configuration. The system state contains critical components like:

  • Registry
  • COM+ Class Registration database
  • Boot files
  • Active Directory (for domain controllers)
  • SYSVOL (for domain controllers)

We'll implement a PowerShell-based solution that combines:

  1. Azure VM automation accounts
  2. Windows Server Backup feature
  3. Azure Storage for backup retention
  4. Azure Automation for scheduling

1. Enable Windows Server Backup Feature

First, we need to install the Windows Server Backup feature on the target VM:


# PowerShell to install Windows Server Backup
Install-WindowsFeature -Name Windows-Server-Backup -IncludeManagementTools

2. Create Backup Script

Save this as SystemStateBackup.ps1:


# Define backup parameters
$backupLocation = "D:\SystemStateBackups"
$backupPolicy = New-WBPolicy

# Add system state to backup
$systemState = Get-WBSystemState
Add-WBBackupItem -Policy $backupPolicy -Item $systemState

# Configure backup target  
$backupTarget = New-WBBackupTarget -NetworkPath "\\yourstorageaccount.file.core.windows.net\backupshare" -Credential (Get-Credential)
Add-WBBackupTarget -Policy $backupPolicy -Target $backupTarget

# Set backup schedule (will be handled by Azure Automation)
Start-WBBackup -Policy $backupPolicy -Async

3. Deploy Azure Automation

Create an Azure Automation account and import these modules:

  • AzureRM.Profile
  • AzureRM.Compute
  • AzureRM.Automation

4. Create Automation Runbook

This runbook will execute our backup script:


<#
.DESCRIPTION
Executes system state backup on target Azure VM
#>

param(
    [Parameter(Mandatory=$true)]
    [string]$VMName,
    
    [Parameter(Mandatory=$true)] 
    [string]$ResourceGroupName
)

$connection = Get-AutomationConnection -Name AzureRunAsConnection
Connect-AzureRmAccount -ServicePrincipal -Tenant $connection.TenantID 
    -ApplicationId $connection.ApplicationID -CertificateThumbprint $connection.CertificateThumbprint

# Get VM credentials
$cred = Get-AutomationPSCredential -Name 'VMCredential'

# Execute remote PowerShell
Invoke-AzureRmVMRunCommand -ResourceGroupName $ResourceGroupName 
    -Name $VMName -CommandId 'RunPowerShellScript' 
    -ScriptPath 'SystemStateBackup.ps1' -Parameter @{credential=$cred}

Retention Policy

To implement a 30-day retention policy, modify the script:


# Add retention policy
Set-WBPolicy -Policy $backupPolicy -DailyBackup -BackupTime (Get-Date -Hour 2 -Minute 0 -Second 0)

Monitoring and Alerts

Create an Azure Alert for failed backup jobs:


# PowerShell to create alert
$action = New-AzureRmAlertRuleEmail -CustomEmail admin@yourdomain.com
Add-AzureRmMetricAlertRule -Name "BackupFailedAlert" -Location "EastUS" 
    -ResourceGroup "YourRG" -TargetResourceId "/subscriptions/.../yourAutomationAccount" 
    -MetricName "JobsFailed" -Operator GreaterThan -Threshold 0 -WindowSize 00:60:00 -TimeAggregationOperator Total -Actions $action

To restore from a system state backup:


# Get available backups
$backups = Get-WBBackupSet -BackupTarget $backupTarget

# Start restoration
Start-WBSystemStateRecovery -BackupSet $backups[0] -MachineName "YourServer" -Location "D:\TempRestore" -Force

When working with Windows Azure Virtual Machines, many administrators face a common dilemma: while Azure Backup easily handles data protection, system state backups require additional configuration. The system state contains critical components like the registry, COM+ database, boot files, and Active Directory (if applicable), making it essential for full system recovery.

Before implementing the solution, ensure you have:

  • Azure PowerShell module installed (Az 5.0 or later)
  • Contributor permissions on the Recovery Services vault
  • Windows Server Backup feature enabled on the target VM
  • Network connectivity between the VM and Azure Backup vault

Here's how to configure scheduled system state backups:

1. Create a Recovery Services Vault

# Connect to Azure account
Connect-AzAccount

# Create new Recovery Services vault
$vault = New-AzRecoveryServicesVault -Name "SystemStateVault" -ResourceGroupName "Backup-RG" -Location "WestUS2"

# Set vault context
Set-AzRecoveryServicesVaultContext -Vault $vault

2. Configure Backup Policy

# Create new backup policy
$policy = New-AzRecoveryServicesBackupProtectionPolicy -Name "DailySystemStatePolicy" 
    -WorkloadType "MSSQL" -BackupManagementType "AzureVM" 
    -ScheduleWindowDuration (New-TimeSpan -Hours 12) 
    -ScheduleWindowStartTime (Get-Date -Hour 22 -Minute 0 -Second 0) 
    -ScheduleRunFrequency Weekly -ScheduleRunDays @("Monday","Tuesday","Wednesday","Thursday","Friday") 
    -RetentionPolicy (Get-AzRecoveryServicesBackupRetentionPolicyObject -WorkloadType "MSSQL") 
    -Compression $true -FullBackup

3. Enable Backup for the VM

# Get the target VM
$vm = Get-AzVM -ResourceGroupName "Prod-RG" -Name "WebServer01"

# Enable backup protection
Enable-AzRecoveryServicesBackupProtection -Policy $policy -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName

For complete automation, create a PowerShell script that runs on the VM itself to initiate system state backups:

# Script to be run on the VM
$backupLocation = "D:\SystemStateBackups"
$wbadminCommand = "wbadmin start systemstatebackup -backupTarget:$backupLocation -quiet"

# Create directory if it doesn't exist
if (!(Test-Path $backupLocation)) {
    New-Item -ItemType Directory -Path $backupLocation
}

# Execute system state backup
Invoke-Expression $wbadminCommand

# Optionally copy the backup to Azure storage
$storageAccount = "mystorageaccount"
$storageKey = "storageaccountkey"
$containerName = "systemstatebackups"

$context = New-AzStorageContext -StorageAccountName $storageAccount -StorageAccountKey $storageKey
Set-AzStorageBlobContent -File "$backupLocation\*" -Container $containerName -Context $context -Force

After implementing the solution, verify backups are working correctly:

# Check backup jobs
Get-AzRecoveryServicesBackupJob -VaultId $vault.ID

# List recovery points
$backupItem = Get-AzRecoveryServicesBackupItem -BackupManagementType "AzureVM" -WorkloadType "MSSQL" -VaultId $vault.ID
Get-AzRecoveryServicesBackupRecoveryPoint -Item $backupItem -VaultId $vault.ID

When you need to restore from a system state backup:

# Identify the recovery point
$rp = Get-AzRecoveryServicesBackupRecoveryPoint -Item $backupItem -VaultId $vault.ID | Sort-Object -Property RecoveryPointTime -Descending | Select-Object -First 1

# Start restore job
Restore-AzRecoveryServicesBackupItem -RecoveryPoint $rp[0] -StorageAccountName "targetstorageaccount" -StorageAccountResourceGroupName "targetRG" -VaultId $vault.ID -VaultLocation $vault.Location
  • Test restores periodically to validate backup integrity
  • Monitor backup jobs using Azure Monitor alerts
  • Consider using Azure Automation for more complex scheduling needs
  • Store system state backups separately from data backups
  • Implement role-based access control for backup operations