We have had some tough time backing up virtual machines based out of customized VHD and running OS prior to Windows Server 2008 R2 SP1, The reason being, Azure Virtual Machine Guest agent does is not supported in any of these OS, i.e. Windows Server 2003 R2, Windows XP, etc. (You might wonder is it still possible to host VM’s running these legacy OS and the answer is YES).

Now that Microsoft have released the feature to snapshot the VHD blobs and ability to restore them, we have come up with the below script which can be set up in the Azure Automation as a PowerShell based runbook (NOT Workbook).

The script below is used by us in a project to take blob snapshot of all the VMs, running every 8 hours via Azure Automation Runbook.

##Setting Global Paramaters##
$date = Get-Date -UFormat “%Y-%m-%d-%H-%M”

#Connecting as AzureRunas Principle account
$connectionName = “AzureRunAsConnection”
try
{
# Get the connection “AzureRunAsConnection ”
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName

“Logging in to Azure…”
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = “Connection $connectionName not found.”
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
#Select-AzureRmSubscription -SubscriptionName $SubscriptionName | Out-Null

$ResourceGroups = Get-AzureRmResourceGroup

foreach($ResourceGroup in $ResourceGroups)
{
Write-Verbose -Verbose $ResourceGroup.ResourceGroupName
$VM_Names = @(Get-AzureRmResource | where {$_.ResourceType -like “Microsoft.*/virtualMachines”})
foreach($VM_Name in $VM_Names)
{
$VM = Get-AzureRmVM -ResourceGroupName $VM_Name.ResourceGroupName -Name $VM_Name.Name #getting the virtual machine object
$StrAccName =([System.Uri]$VM.StorageProfile.OsDisk.Vhd.uri).Host.Split(‘.’)[0] #getting SA of VHD.
$RGName = Get-AzureRmStorageAccount | where {$_.StorageAccountName -eq $StrAccName} | Select-Object -ExpandProperty ResourceGroupName #getting RG of VHD.
$VHDName = $VM.StorageProfile.OsDisk.vhd.Uri.Split(‘/’)[-1] #getting VHD name.
$SrcCntName = $VM.StorageProfile.OsDisk.vhd.Uri.Split(‘/’)[-2] #Source container name.
$StrAcc = Get-AzureRmStorageAccount -AccountName $StrAccName -ResourceGroupName $RGName
#$Ctx = New-AzureStorageContext $StrAccName -StorageAccountKey $StrAccKey #SA context
$CntNames = $CntNames = Get-AzureStorageContainer -Context $strAcc.Context | Select-Object -ExpandProperty Name #getting all the containers

Write-Verbose -Verbose $VM.Name
Write-Verbose -Verbose $StrAcc.StorageAccountName
Start-Sleep 2
Write-Verbose -Verbose “Creating snapshot for OS disk $VHDName ….”
$VMblob = Get-AzureRMStorageAccount -Name $StrAccName -ResourceGroupName $RGName |
Get-AzureStorageContainer | where {$_.Name -eq $SrcCntName} | Get-AzureStorageBlob | where {$_.Name -eq $VHDName -and $_.ICloudBlob.IsSnapshot -ne $true}
$VMsnap = $VMblob.ICloudBlob.CreateSnapshot() #Cresting snapshot
Start-Sleep 2
Write-Host “OS disk $VHDName Snapshot created….!!!!”
Start-Sleep 2
$VMSnapshots = Get-AzureStorageBlob –Context $strAcc.Context -Container $SrcCntName | Where-Object {$_.ICloudBlob.IsSnapshot -and $_.Name -eq $VHDName -and $_.SnapshotTime -lt (Get-Date).AddDays(-14) }
if($VMSnapshots -ne $null)
{
Write-Host “Deleting snapshots prior to 14 days for OS Disk $VHDName ….”
foreach($VMSnapshot in $VMSnapshots)
{
$VMSnapshot.ICloudBlob.Delete()
Write-Host ” OS Disk $VHDName snapshots deleted…!!!”
}
}
#creating Snapshot for the data disks
$DataDiskName = @{}
#loop for all the data disks identified for the VM
for($i=0;$i -lt $VM.StorageProfile.DataDisks.Count;$i++)
{
$DataDiskName[$i] = $VM.StorageProfile.DataDisks[$i].Vhd.Uri.Split(‘/’)[-1]
Write-Host “Creating snapshot for Data disk $DataDiskName[$i] ….”
$Datablob = Get-AzureRMStorageAccount -Name $StrAccName -ResourceGroupName $RGName | Get-AzureStorageContainer | where {$_.Name -eq $SrcCntName} | Get-AzureStorageBlob | where {$_.Name -eq $DataDiskName[$i] -and $_.ICloudBlob.IsSnapshot -ne $true}
$VMDatasnap = $Datablob.ICloudBlob.CreateSnapshot() #Creating snapshot
Start-Sleep 2
Write-Host “Data disk $DataDiskName[$i] Snapshot created….!!!!”
Start-Sleep 2
$VMDataSnapshots = Get-AzureStorageBlob –Context $strAcc.Context -Container $SrcCntName | Where-Object {$_.ICloudBlob.IsSnapshot -and $_.Name -eq $DataDiskName[$i] -and $_.SnapshotTime -lt (Get-Date).AddDays(-14) }
if($VMSnapshots -ne $null)
{
Write-Host “Deleting snapshots prior to 14 days for$DataDiskName[$i]….”
foreach($VMDataSnapshot in $VMDataSnapshots)
{
$VMDataSnapshot.ICloudBlob.Delete()
Write-Host “$DataDiskName[$i] Snapshots prior to 14 days deleted…!!!”
}
}
}

}
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Bitnami