A Recovery Services vault is an online storage entity used to backup workloads in or to Azure based on the Azure Resource Manager model.
Sometimes you need to delete a vault with all it’s cloud backup (protected) items, such as IaaS virtual machines (VMs) backups and backups for SQL Server databases running in those VMs.
But this is not as easy as it sounds, and this because you should know that you cannot delete a vault that contains any protected data sources or contains any backup data, or backup items in a soft deleted state.
If you try to delete the vault without removing any type of protected data sources or backup items, you will encounter one of the following error messages, depending on the way you delete the vault.


As the error message indicates, the vault is still holding some backup items.

Because it takes some time to clean up all these different cloud backup items and the Recovery services vault itself trough the Azure Portal, I always use the below Azure PowerShell script to do all the work for me.
This Azure PowerShell script will do all of the following:
- Check if the PowerShell window is running as Administrator (which is a requirement), otherwise the Azure PowerShell script will be exited.
- Disable soft delete for the Azure Backup Recovery Services vault.
- After disabling soft delete, checks if there are cloud backup items in a soft-deleted state and if so reverse the delete operation.
- Stop protection and delete data for all cloud backup-protected items.
- Delete the Recovery Services vault.
- Delete the resource group holding the Recovery Services vault and the one used for the instant recovery, and this without confirmation.
To use the script copy and save it as Delete-an-Azure-Backup-RecoveryServices-vault.ps1 or download it from GitHub. Then before using the script, adjust all variables to your use (you can find an adjusted example in a screenshot below) and then run the customized script with Administrator privileges from Windows Terminal, Visual Studio Code, or Windows PowerShell. Or you can simply run it from Cloud Shell.
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. And if you are using multiple Azure subscriptions, select the proper subscription with the Get-AzSubscription cmdlet before running the script.
<#
.SYNOPSIS
A script used to delete an Azure Backup Recovery Services vault and all cloud backup items.
.DESCRIPTION
A script used to delete an Azure Backup Recovery Services vault.
First of all the script will check if PowerShell runs as an Administrator (when not running from Cloud Shell), otherwise the script will be exited as this is required.
Next soft delete is disabled for the selected , and all soft-deleted backup items are reversed.
Then all cloud backup items are removed before the Recovery Services vault is removed.
Afterwards the resource groups holding the Recovery Services vault and the one used for the instant recovery are deleted.
.NOTES
Filename: Delete-an-Azure-Backup-RecoveryServices-vault.ps1
Created: 17/11/2020
Last modified: 19/10/2021
Author: Wim Matthyssen
PowerShell: Azure PowerShell or Azure Cloud Shell
Version: Install latest Azure PowerShell modules
Action: Change variables where needed to fit your needs
Disclaimer: This script is provided "As Is" with no warranties.
.EXAMPLE
.\Delete-an-Azure-Backup-RecoveryServices-vault.ps1
.LINK
https://wmatthyssen.com/2020/11/17/azure-backup-remove-a-recovery-services-vault-and-all-cloud-backup-items-with-azure-powershell/
#>
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Variables
$rgBackup = #<your Recovery Services vault rg here> The Azure resource group in which the Recovery Services vault is stored. Example: "rg-hub-myh-backup"
$rgBackupInstanRecovery = #<your Instant restore rg here> The Azure resource group in which the instant recovery snapshots are stored. Example: "rg-hub-myh-backup-irp-01"
$vaultName = #<your Recovery Services vault name here> The name of the recovery Service vault resource you want to delete. Example: "rsv-bck-hub-myh-weu-01"
$vault = Get-AzRecoveryServicesVault -ResourceGroupName $rgBackup -Name $vaultName
$global:currenttime= Set-PSBreakpoint -Variable currenttime -Mode Read -Action {$global:currenttime= Get-Date -UFormat "%A %m/%d/%Y %R"}
$foregroundColor1 = "Red"
$foregroundColor2 = "Yellow"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Check if PowerShell runs as Administrator (when not running from Cloud Shell), otherwise exit the script
if ($PSVersionTable.Platform -eq "Unix") {
Write-Host ($writeEmptyLine + "# Running in Cloud Shell" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
# Start script execution
Write-Host ($writeEmptyLine + "# Script started. Depending on the amount of backup data it can take some time to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
} else {
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdministrator = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
# Check if running as Administrator, otherwise exit the script
if ($isAdministrator -eq $false) {
Write-Host ($writeEmptyLine + "# Please run PowerShell as Administrator" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
Start-Sleep -s 3
exit
}
else {
# If running as Administrator, start script execution
Write-Host ($writeEmptyLine + "# Script started. Depending on the amount of backup data it can take some time to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
}
}
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Suppress breaking change warning messages
Set-Item Env:\SuppressAzurePowerShellBreakingChangeWarnings "true"
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Disable soft delete for the Azure Backup Recovery Services vault
Set-AzRecoveryServicesVaultProperty -Vault $vault.ID -SoftDeleteFeatureState Disable
Write-Host ($writeEmptyLine + " # Soft delete disabled for Recovery Service vault " + $vault.Name + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Check if there are backup items in a soft-deleted state and reverse the delete operation
$containerSoftDelete = Get-AzRecoveryServicesBackupItem -BackupManagementType AzureVM -WorkloadType AzureVM -VaultId $vault.ID | Where-Object {$_.DeleteState -eq "ToBeDeleted"}
foreach ($item in $containerSoftDelete) {
Undo-AzRecoveryServicesBackupItemDeletion -Item $item -VaultId $vault.ID -Force -Verbose
}
Write-Host ($writeEmptyLine + "# Undeleted all backup items in a soft deleted state in Recovery Services vault " + $vault.Name + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Stop protection and delete data for all backup-protected items
$containerBackup = Get-AzRecoveryServicesBackupItem -BackupManagementType AzureVM -WorkloadType AzureVM -VaultId $vault.ID | Where-Object {$_.DeleteState -eq "NotDeleted"}
foreach ($item in $containerBackup) {
Disable-AzRecoveryServicesBackupProtection -Item $item -VaultId $vault.ID -RemoveRecoveryPoints -Force -Verbose
}
Write-Host ($writeEmptyLine + "# Deleted backup date for all cloud protected items in Recovery Services vault " + $vault.Name + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Delete the Recovery Services vault
Remove-AzRecoveryServicesVault -Vault $vault -Verbose
Write-Host ($writeEmptyLine + "# Recovery Services vault " + $vault.Name + " deleted" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Delete the resource groups holding the Recovery Services vault and the one used for the instant recovery and this without confirmation
Get-AzResourceGroup -Name $rgBackup | Remove-AzResourceGroup -Force -Verbose
Get-AzResourceGroup -Name $rgBackupInstanRecovery | Remove-AzResourceGroup -Force -Verbose
Write-Host ($writeEmptyLine + "# Resource groups " + $vault.ResourceGroupName + " and " + $rgBackupInstanRecovery + " deleted" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script completed
Write-Host ($writeEmptyLine + "# Script completed" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Different steps in the script
In the script we can break down the following steps:
First of all Soft Delete is disabled for the Azure Backup Recovery Services vault.


Then the script checks if there are backup items in a soft-deleted state and if so it will reverse the delete operation.


Next it will stop protection and delete all data for the cloud backup-protected items.


When all cloud backup items are removed the Recovery Services vault is deleted.


And finally the script removes the resource group which held the Recovery Services vault and the one used for the instant recovery without confirmation.

I hope this Azure PowerShell script is useful for you whenever you need to clean up and delete a Recovery Services vault and all it’s cloud backup items.
If you have any questions or recommendations about it, feel free to contact me through my Twitter handle (@wmatthyssen) or to just leave a comment.
Pingback: Latest Cloud News: Apple On K8s, IoT, Microsoft Pluton And More! (November 20, 2020 – Build5Nines Weekly) | Build5Nines
Pingback: Festive Tech Calendar 2020: Let’s help to get your Azure Backup implementation under control – Wim Matthyssen
Thank you! This saved me tons of time today!
LikeLike
Did not work for me, but this is maybe cornercase 🙂 I searched all over and finally found the answer in a 17+ minute video from msft, where at around 8 minutes it is stated that if you have hybrid solutions, then items cannot be removed manually, but you have to (simply) unregister the hybrid service.
LikeLike
Hi Joel, as stated this script only works for your cloud resources not for your hybrid resources.
LikeLike