Skip to content
Menu
Tech Automation Blog
  • About Author
  • Contact
Tech Automation Blog

Azure Virtual Machine backup report using Powershell

Posted on August 17, 2019February 27, 2022

Update : updated script to support Azure Az powershell module.

A good backup strategy is very important for any Organization – be it on-premises or cloud. However, cloud providers have made it very easy with different cloud based backup and recovery solutions.

Microsoft Azure provides Azure Recovery Services for backup and recovery solution on cloud. It is very important to have a quick report on configured backup items and status. Therefore, It helps administrators to stay on top of any backup failure situation or providing quick status report.

Following script generates simple report of Azure based VM backup status and send email.

Before start using this script, make sure, you have Azure Az Module installed and imported on the system. For more information on how to install and configure Az module refer following article : https://docs.microsoft.com/en-us/powershell/azure/new-azureps-module-az?view=azps-5.5.0.

<#
.SYNOPSIS
	Script to generate Azure VM Backup status Report and send email to subscribers.

.DESCRIPTION
	Script to generate Azure VM Backup status Report and send email to subscribers.
	NOTE : Login to Azure Account to run the script. 

.PARAMETER mailFrom
	Email id from which email will be sent.
    Required: True
	Type: String

.PARAMETER mailTo
	Email id(s) to which Backup status report email will be sent. For multiple email ids, use comma separated list.
    Required: True
    Type: String

.PARAMETER smtpServer
	SMTP server name to send the email.
	Required: True
	Type: String
	
.PARAMETER smtpPort
	SMTP Port number. This could be standard 25 or it could be different for your Organization.
	Required: True
	Type: int

.NOTES
	Author: Arindam Hazra
	Version: 1.0.0
#>
Param(
    [Parameter(Mandatory=$true)]
    [string]$mailFrom,
    [Parameter(Mandatory=$true)]
    [string]$mailTo,
    [Parameter(Mandatory=$true)]
    [string]$smtpServer,
    [Parameter(Mandatory=$true)]
    [int]$smtpPort
)
#declare and initiate variables
$subject = "$subscription Subscription Azure VM Backup Status"
$today = get-date -Format ("MM-dd-yyyy")
$oFile = "$($env:TEMP)\Backup_Status_$($today).csv"
$backupStatHTML = "$($env:TEMP)\Backup_Status_$($today).html"
$listOfAttachments = @() 
if(Test-Path $oFile){
    Remove-Item $oFile -Force
}
if(Test-Path $backupStatHTML){
    Remove-Item $backupStatHTML -Force
}
"VirtualMachine, VM Status, Vault Name, Vault Resource Group,  Protection Status, Protection State, Last Backup Status,Last Backup Date, Policy Name, Container Type, Container Name "  |  Out-File $oFile -Append -Encoding ASCII

$allServerBackupStatusArray = @()
Get-AzRecoveryServicesVault | ForEach-Object{
    $vault = $_.Name
    $vaultResourceGroup = $_.ResourceGroupName
    Set-AzRecoveryServicesVaultContext -Vault $_
    Get-AzRecoveryServicesBackupContainer -ContainerType AzureVM | ForEach-Object{
        Get-AzRecoveryServicesBackupItem -Container $_ -WorkloadType AzureVM | ForEach-Object{
            $protectionStatus = $protectionState = $lastBackupStatus = $lastBackupTime = $policyName = $containerType = $containerName = $vmDetails = $vmStatus = ""
            $vmName = $_.VirtualMachineId.Split("/")[-1]
            $vmDetails = Get-AzResource -ResourceType Microsoft.Compute/virtualMachines -Name $vmName
            if($vmDetails){$vmStatus = "Active VM"}else{$vmStatus = "Deleted VM"}
            $protectionStatus = $_.protectionStatus
            $protectionState = $_.protectionState
            $lastBackupStatus = $_.lastBackupStatus
            $lastBackupTime = $_.lastBackupTime
            $policyName = $_.ProtectionPolicyName
            $containerType = $_.containerType
            $containerName = $_.containerName.Split(";")[0]
            $obj = New-Object psobject
            $obj | Add-Member NoteProperty VaultName $vault
            $obj | Add-Member NoteProperty VaultResourceGroup $vaultResourceGroup
            $obj | Add-Member NoteProperty VMName $vmName
            $obj | Add-Member NoteProperty VMStatus $vmStatus
            $obj | Add-Member NoteProperty ProtectionStatus $protectionStatus
            $obj | Add-Member NoteProperty ProtectionState $protectionState
            $obj | Add-Member NoteProperty LastBackupStatus $lastBackupStatus
            $obj | Add-Member NoteProperty LastBackupTime $lastBackupTime
            $obj | Add-Member NoteProperty PolicyName $policyName
            $obj | Add-Member NoteProperty ContainerType $containerType
            $obj | Add-Member NoteProperty ContainerName $containerName
            $allServerBackupStatusArray += $obj
        }
    }
}

#Get All VM Backup Status
Get-AzVM | Select-Object Name | ForEach-Object{
    $vm = $_.Name
    if($allServerBackupStatusArray.VMName.Contains($vm)){
        $details = $allServerBackupStatusArray | Where-Object{$_.VMName -eq $vm}
        "$vm,Active VM,$($details.VaultName),$($details.VaultResourceGroup),$($details.ProtectionStatus),$($details.ProtectionState),$($details.LastBackupStatus),$($details.LastBackupTime),$($details.PolicyName),$($details.ContainerType),$($details.ContainerName)" |  Out-File $oFile -Append -Encoding ASCII
    }
    else{
        "$vm,Active VM,,,,,,,,," |  Out-File $oFile -Append -Encoding ASCII
    }
}
$listOfAttachments += $oFile

#Get Summary of Backup Status to print in email
$completedBackupCount = $failedBackupCount = $noBackupCount = $protectedVMCount = $unprotectedVMCount = $activeVMCount = $deletedVMCount = 0
Import-Csv $oFile | ForEach-Object{
    if($_.'Last Backup Status' -eq 'Completed'){
        $completedBackupCount +=1
    }
    if($_.'Last Backup Status' -eq 'Failed'){
        $failedBackupCount +=1
    }
    if($_.'Last Backup Status' -eq ''){
        $noBackupCount +=1
    }
    if($_.'Last Backup Status' -eq ''){
        $noBackupCount +=1
    }
    if($_.'Protection State' -eq 'Protected'){
        $protectedVMCount +=1
    }
    if($_.'Protection State' -ne 'Protected'){
        $unprotectedVMCount +=1
    }
    if($_.'VM Status' -eq 'Active VM'){
        $activeVMCount +=1
    }
    if($_.'VM Status' -eq 'Deleted VM'){
        $deletedVMCount +=1
    }
}

#generate HTML content
$Header = @"
<style>
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #4D7657;color:white}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
P {color:Green;font-weight:bold}
H4{color:Blue;font-weight:normal}
H3{color:Blue;font-weight:bold}
</style>
<!DOCTYPE html>
<html>
<head>
</head>
<body style="background-color:#D6EBF2;Font:Arial">
"@ 
$Header | Out-File $backupStatHTML -append 

$tableHeader = @"
<div id="head" style="Text-Align:center">
<h3 style="color:Blue;font-weight:bold">Azure Virtual Machine Backup Summary Report. For details, refer attachment</h3>
<hr />
</div>
"@
$tableHeader | Out-File $backupStatHTML -append
@"
<div  style="display:inline;Text-Align:center">
<table><tr><th>Backup Completed</th><th>Backup Failed</th><th>No Backup</th><th>Protected VM</th><th>Unprotected VM</th><th>Deleted VM in Backup</th></tr>
<tr><td>$completedBackupCount</td><td>$failedBackupCount</td><td>$noBackupCount</td><td>$protectedVMCount</td><td>$unprotectedVMCount</td><td>$deletedVMCount</td></tr></table>
</div>
</div>
</body>
</html>
"@ | Out-File $backupStatHTML -append 
#Send email to stake holders
$mailMessageParameters = @{
	From       = $mailFrom
	To         = $mailTo
	Subject    = $subject
	SmtpServer = $smtpServer
	Port	   = $smtpPort
	Body       = (gc $backupStatHTML) | Out-String
	Attachments =  $Global:ListOfAttachments	
}
Send-MailMessage @mailMessageParameters -BodyAsHtml -UseSsl
#Clean up files created during script execution
if(Test-Path $oFile){Remove-Item $oFile -Force}
if(Test-Path $backupStatHTML){Remove-Item $backupStatHTML -Force}
Stop-Transcript
Exit

Download above script and save it with a .ps1 file extension. Open powershell console and, login to your Azure account using – Login-AzAccount. It will prompt you to enter your Azure credentials.

This image has an empty alt attribute; its file name is image-3.png
Login to Azure account

Once you login to Azure, run the powershell script saved in previous step. You need to pass all required parameters defined in the script. Once the script completes, it will send an email with attached report.However, if you don’t have a mail server configured, a CSV file will also be available as a report for you.

Pass required parameters

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on LinkedIn (Opens in new window) LinkedIn
May 2025
M T W T F S S
 1234
567891011
12131415161718
19202122232425
262728293031  
« May    

Recent Posts

  • Monitor and alert Azure Service Health issues May 5, 2020
  • AWS IAM User access review May 3, 2020
  • Integrate Azure Security Center with Event Hub April 28, 2020
  • Add Tags to Azure Subscription April 24, 2020
  • Automate Azure billing report in Excel March 6, 2020

Categories

©2025 Tech Automation Blog | Powered by SuperbThemes