Azure Azure Backup Azure PowerShell

Azure Backup: Create a Recovery Services vault with Azure PowerShell

[September 12, 2020 – Updated post] 

In this blog post, you’ll learn how to create a Recovery Services vault using an Azure PowerShell script.

A Recovery Services vault is an online storage entity utilized to back up workloads to or within Azure, following the Azure Resource Manager model.

You can use it to store backup data for a variety of Azure resources, including IaaS virtual machines (both Windows and Linux), as well as SQL Server databases running within those VMs. Moreover, it’s capable of backing up your file share data in Azure Files. With the use of the Microsoft Azure Recovery Services (MARS) agent, you also have the option to back up and restore files, folders, and the system state of an on-premises server. Additionally, when integrated with System Center Data Protection Manager (SCDPM) or Azure Backup Server (MABS), it allows you to create cloud backups alongside disk backups from your on-premises servers.

Nowadays, creating or managing a Recovery Services vault through the Azure portal is relatively straightforward. However, the process becomes even quicker and more efficient when automation is implemented using a scripting language like Azure PowerShell.

Therefore, I’ve provided an Azure PowerShell script below, which I frequently use to set up an Azure Backup Recovery Services vault in a specific Azure subscription.

This script includes the following steps and configurations:

  • Remove the breaking change warning messages.
  • Change the current context to use a management subscription holding your central Log Analytics workspace.
  • Save the Log Analytics workspace from the management subscription as a variable.
  • Change the current context to the specified subscription.
  • Store a specified set of tags in a hash table.
  • Register required Azure resource provider (Microsoft.RecoveryServices) in your subscription (only necessary if you use Azure Backup for the first time), if not already registered.
  • Create a resource group backup if one does not already exist. Also, apply the necessary tags to this resource group.
  • Create a resource group backup irp if one does not already exist. Also, apply the necessary tags to this resource group.
  • Create the Recovery Services vault if it does not exist.
  • Set specified tags on the Recovery Services vault.
  • Specify the type of backup storage redundancy for the Recovery Services vault (which can be modified only if there are no backup items protected in the vault).
  • Enable Cross Region Restore (CRR).
  • Set the log and metrics settings for the Recovery Services vault if they don’t exist.
  • Remove the default backup protection policies.


To use the script, first make a copy and save it as “Create-an-Azure-Backup-Recovery-Services-vault.ps1” or you can download it directly from GitHub.

Before utilizing the script, adjust all variables according to your requirements (an example is provided below). Once adjusted, run the customized script using Windows TerminalVisual Studio Code, or Windows PowerShell. Or you can simply run it from Cloud Shell.


You can only change the Storage Replication type (Locally redundant/ Geo-redundant) for a Recovery Services vault when there is no backup data configured or stored in the vault. Once you configure any backup, the option to modify the replication type is disabled.

As a best practice you should use the default Geo-redundant setting when you use Azure Backup as your primary backup location.


Prerequisites

  • An Azure subscription, preferably more than one if you plan to follow the Cloud Adoption Framework (CAF) enterprise-scale architecture. This includes a connectivity and/or management subscription, as well as different landing zone subscriptions , like a corporate production subscription.
  • An Azure Administrator account with the necessary RBAC roles.
  • An existing Log Analytics workspace.
  • Version 10.4.1 of the Azure Az PowerShell module is required.
  • Change all the variables in the script where needed to fit your needs (you can find an adjusted example in one of the screenshots below).







Azure PowerShell script

If you are not running the script from Cloud Shell, don’t forget to sign in with the Connect-AzAccount cmdlet to connect your Azure account.


After adjusting the variables to suit your needs, proceed to run the script with the required parameters:

.\Create-Azure-Backup-Recovery-Services-vault -SubscriptionName <"your Azure subscription name here">



<#
.SYNOPSIS

A script used to create an Azure Backup Recovery Services vault to backup different workloads in an Azure subscription.

.DESCRIPTION

A script used to create an Azure Backup Recovery Services vault in a resource group to backup different workloads in an Azure subscription.
The script will do all of the following:

Remove the breaking change warning messages.
Change the current context to use a management subscription holding your central Log Analytics workspace.
Save the Log Analytics workspace from the management subscription as a variable.
Change the current context to the specified Azure subscription.
Store a specified set of tags in a hash table.
Register required Azure resource provider (Microsoft.RecoveryServices) in your subscription (only necessary if you use Azure Backup for the first time), if not already registered.
Create a resource group backup if one does not already exist. Also, apply the necessary tags to this resource group.
Create a resource group backup irp if one does not already exist. Also, apply the necessary tags to this resource group.
Create the Recovery Services vault if it does not exist.
Set specified tags on the Recovery Services vault.
Specify the type of backup storage redundancy for the Recovery Services vault (which can be modified only if there are no backup items protected in the vault).
Enable Cross Region Restore (CRR).
Set the log and metrics settings for the Recovery Services vault if they don't exist.
Remove the default backup protection policies.

.NOTES

Filename:       Create-Azure-Backup-Recovery-Services-vault.ps1
Created:        11/09/2020
Last modified:  11/10/2023
Author:         Wim Matthyssen
Version:        3.0
PowerShell:     Azure PowerShell and Azure Cloud Shell
Requires:       PowerShell Az (v10.4.1)
Action:         Change variables were needed to fit your needs. 
Disclaimer:     This script is provided "as is" with no warranties.

.EXAMPLE

Connect-AzAccount
Get-AzTenant (if not using the default tenant)
Set-AzContext -tenantID "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx" (if not using the default tenant)
.\Create-Azure-Backup-Recovery-Services-vault -SubscriptionName <"your Azure subscription name here">

.LINK

https://wmatthyssen.com/2022/08/31/azure-backup-create-a-recovery-services-vault-with-azure-powershell/
#>

## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Variables

$purpose = "backup"
$region = #<your region here> The used Azure public region. Example: "westeurope"
$providerNameSpace = "Microsoft.RecoveryServices"

$rgNameBackup = #<your backup resource group name here> The name of the Azure resource group in which your new or existing Recovery Services vault deployed. Example: "rg-prd-myh-avd-backup-01"
$rgNameBackupIrp = #<your backup irp resource group name here> The name of the Azure resource group in which your store your instant restore snapshots . Example: "rg-prd-myh-avd-backup-irp-01"

$logAnalyticsWorkSpaceName = #<your Log Analytics workspace name here> The name of your existing Log Analytics workspace. Example: "law-hub-myh-01"

$vaultName = #<your Recovery Services vault name here> The name of your new Recovery Services vault. Example: "rsv-prd-myh-bck-we-01"
$backupStorageRedundancy = "GeoRedundant" # "LocallyRedundant" (LRS) - "ZoneRedundant" (ZRS)
$vaultDiagnosticsName = "diag" + "-" + $vaultName

$tagSpokeName = #<your environment tag name here> The environment tag name you want to use. Example:"Env"
$tagSpokeValue = #<your environment tag value here> The environment tag value you want to use. Example: "Hub"
$tagCostCenterName  = #<your costCenter tag name here> The costCenter tag name you want to use. Example:"CostCenter"
$tagCostCenterValue = #<your costCenter tag value here> The costCenter tag value you want to use. Example: "23"
$tagCriticalityName = #<your businessCriticality tag name here> The businessCriticality tag name you want to use. Example: "Criticality"
$tagCriticalityValue = #<your businessCriticality tag value here> The businessCriticality tag value you want to use. Example: "High"
$tagPurposeName  = #<your purpose tag name here> The purpose tag name you want to use. Example:"Purpose"
$tagPurposeValue = "$($purpose[0].ToString().ToUpper())$($purpose.SubString(1))"

Set-PSBreakpoint -Variable currenttime -Mode Read -Action {$global:currenttime = Get-Date -Format "dddd MM/dd/yyyy HH:mm"} | Out-Null 
$foregroundColor1 = "Green"
$foregroundColor2 = "Yellow"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Remove the breaking change warning messages

Set-Item -Path Env:\SuppressAzurePowerShellBreakingChangeWarnings -Value $true | Out-Null
Update-AzConfig -DisplayBreakingChangeWarning $false | Out-Null
$warningPreference = "SilentlyContinue"

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Write script started

Write-Host ($writeEmptyLine + "# Script started. Without errors, it can take up to 2 minutes to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Change the current context to use a management subscription holding your central Log Anlytics workspace

# Replace <your subscription purpose name here> with purpose name of your subscription. Example: "*management*"
$subNameManagement = Get-AzSubscription | Where-Object {$_.Name -like "*management*"}

Set-AzContext -SubscriptionId $subNameManagement.SubscriptionId | Out-Null 

Write-Host ($writeEmptyLine + "# Management subscription in current tenant selected" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Save Log Analytics workspace from the management subscription in a variable

$workSpace = Get-AzOperationalInsightsWorkspace | Where-Object Name -Match $logAnalyticsWorkSpaceName

Write-Host ($writeEmptyLine + "# Log Analytics workspace variable created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Change the current context to the specified subscription

$subName = Get-AzSubscription | Where-Object {$_.Name -like $subscriptionName}

Set-AzContext -SubscriptionId $subName.SubscriptionId | Out-Null 

Write-Host ($writeEmptyLine + "# Specified subscription in current tenant selected" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Register the required Azure resource provider (Microsoft.RecoveryServices) in the current subscription context, if not yet registerd

Register-AzResourceProvider -ProviderNamespace $providerNameSpace | Out-Null

Write-Host ($writeEmptyLine + "# All required resource providers for a Recovery Services vault are currently registering or have already registered" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Store the specified set of tags in a hash table

$tags = @{$tagSpokeName=$tagSpokeValue;$tagCostCenterName=$tagCostCenterValue;$tagCriticalityName=$tagCriticalityValue;$tagPurposeName=$tagPurposeValue}

Write-Host ($writeEmptyLine + "# Specified set of tags available to add" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Create a resource group backup if one does not already exist. Also, apply the necessary tags to this resource group

try {
    Get-AzResourceGroup -Name $rgNameBackup -ErrorAction Stop | Out-Null 
} catch {
    New-AzResourceGroup -Name $rgNameBackup -Location $region -Force | Out-Null   
}

# Save variable tags in a new variable to add tags.
$tagsResourceGroup = $tags

# Set tags rg storage.
Set-AzResourceGroup -Name $rgNameBackup -Tag $tagsResourceGroup | Out-Null

Write-Host ($writeEmptyLine + "# Resource group $rgNameBackup available with tags" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Create a resource group backup irp if one does not already exist. Also, apply the necessary tags to this resource group.

try {
    Get-AzResourceGroup -Name $rgNameBackupIrp -ErrorAction Stop | Out-Null 
} catch {
    New-AzResourceGroup -Name $rgNameBackupIrp -Location $region -Force | Out-Null
}

# Save variable tags in a new variable to add tags.
$tagsResourceGroup = $tags

# Set tags rg storage.
Set-AzResourceGroup -Name $rgNameBackupIrp -Tag $tagsResourceGroup | Out-Null

Write-Host ($writeEmptyLine + "# Resource group $rgNameBackupIrp available with tags" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Create the Recovery Services vault if it does not exist

try {
    Get-AzRecoveryServicesVault -Name $vaultName -ResourceGroupName $rgNameBackup -ErrorAction Stop | Out-Null 
} catch {
    New-AzRecoveryServicesVault -Name $vaultName -ResourceGroupName $rgNameBackup -Location $region | Out-Null
}

Write-Host ($writeEmptyLine + "# Recovery Services vault $vaultName created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Set specified tags on the Recovery Services vault

$vault = Get-AzRecoveryServicesVault -Name $vaultName -ResourceGroupName $rgNameBackup

# Replace exisiting tags on the Recovery Services vault
Update-AzTag -ResourceId ($vault.Id) -Tag $tags -Operation Replace | Out-Null

Write-Host ($writeEmptyLine + "# Tags Recovery Services vault $vaultName set" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Specify the type of backup storage redundancy for the Recovery Services vault (which can be modified only if there are no backup items protected in the vault)

Set-AzRecoveryServicesBackupProperty -Vault $vault -BackupStorageRedundancy $backupStorageRedundancy

Write-Host ($writeEmptyLine + "# Backup storage redundancy is set to $backupStorageRedundancy for Recovery Services vault $vaultName" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Enable Cross Region Restore (CRR)

Set-AzRecoveryServicesBackupProperty -Vault $vault -EnableCrossRegionRestore

Write-Host ($writeEmptyLine + "# Cross Region Restore is enabled for Recovery Services vault $vaultName" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Set the log and metrics settings for the Recovery Services vault if they don't exist

try {
    Get-AzDiagnosticSetting -Name $vaultDiagnosticsName -ResourceId ($vault.Id) -ErrorAction Stop | Out-Null
} catch {   
    $metric = @()
    $metric += New-AzDiagnosticSettingMetricSettingsObject -Enabled $true -Category AllMetrics
    $log = @()
    $log += New-AzDiagnosticSettingLogSettingsObject -Enabled $true -Category AzureBackupReport
    $log += New-AzDiagnosticSettingLogSettingsObject -Enabled $true -Category CoreAzureBackup
    $log += New-AzDiagnosticSettingLogSettingsObject -Enabled $true -Category AddonAzureBackupJobs
    $log += New-AzDiagnosticSettingLogSettingsObject -Enabled $true -Category AddonAzureBackupAlerts
    $log += New-AzDiagnosticSettingLogSettingsObject -Enabled $true -Category AddonAzureBackupPolicy
    $log += New-AzDiagnosticSettingLogSettingsObject -Enabled $true -Category AddonAzureBackupStorage
    $log += New-AzDiagnosticSettingLogSettingsObject -Enabled $true -Category AddonAzureBackupProtectedInstance
    
    New-AzDiagnosticSetting -Name $vaultDiagnosticsName -ResourceId ($vault.Id) -WorkspaceId ($workSpace.ResourceId) -Log $log -Metric $metric | Out-Null
}

Write-Host ($writeEmptyLine + "# Recovery Services vault $vaultName diagnostic settings set" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Remove the default backup protection policies

Remove-AzRecoveryServicesBackupProtectionPolicy -Name "DefaultPolicy" -VaultId $vault.ID -Force | Out-Null
Remove-AzRecoveryServicesBackupProtectionPolicy -Name "HourlyLogBackup" -VaultId $vault.ID -Force | Out-Null
Remove-AzRecoveryServicesBackupProtectionPolicy -Name "EnhancedPolicy" -VaultId $vault.ID -Force | Out-Null

Write-Host ($writeEmptyLine + "# Default Backup protection policies removed from vault $vaultName" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Write script completed

Write-Host ($writeEmptyLine + "# Script completed" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------










I hope this Azure PowerShell script is useful for you and serves as a solid foundation for initiating Azure Backup within your Azure environment(s).

Should you have any questions or suggestions concerning this script, please don’t hesitate to contact me via my Twitter handle (@wmatthyssen) or leave a comment, and I’ll be more than happy to assist.



Unknown's avatar

Wim is an Azure Technical Advisor and Trainer with over fifteen years of Microsoft technology experience. As a Microsoft Certified Trainer (MCT), his strength is assisting companies in the transformation of their businesses to the Cloud by implementing the latest features, services, and solutions. Currently, his main focus is on the Microsoft Hybrid Cloud Platform, and especially on Microsoft Azure and the Azure hybrid services.   Wim is also a Microsoft MVP in the Azure category and a founding board member of the MC2MC user group. As a passionate community member, he regularly writes blogs and speaks about his daily experiences with Azure and other Microsoft technologies.

2 comments on “Azure Backup: Create a Recovery Services vault with Azure PowerShell

  1. Pingback: Azure Back to School: Azure Backup for Azure IaaS resources – Wim Matthyssen

  2. Pingback: Festive Tech Calendar 2020: Let’s help to get your Azure Backup implementation under control – Wim Matthyssen

Leave a comment