You dont have javascript enabled! Please enable it!

Update Azure Backup Policy at Scale using PowerShell

7 Min. Read

Azure Backup is the Azure-based service you can use to back up (or protect) and restore your data in the Microsoft cloud. Azure Backup replaces your existing on-premises or off-site backup solution with a cloud-based solution that is reliable, secure, and cost-competitive.

In this article, we will share with you how to modify and update the Azure backup policy retention at scale using PowerShell.

Introduction

When you start preparing to protect your workloads with Azure Backup, there are multiple prerequisites you want to verify such as:

> Verify supported scenarios and prerequisites.
> Install the Azure VM agent if needed, and verify outbound access for VMs.
> Create a Recovery Services Vault.
> Set up storage for the vault (Local-Redundant or Geo-Redundant).
> Create and configure the backup policy based on your company policy.
> Enable Azure Backup.

You can read more about all the Azure Backup prerequisites and preparation on Microsoft official documentation.

When you plan to create and configure a backup policy in the Azure Portal, you need to specify the policy type such as (Azure Virtual Machine, File Share, SQL Server in Azure VM, or SAP HANA in Azure VM) to create the backup goal. Then when you choose the backup type, you have to set the backup schedule and retention range (daily, weekly, monthly, or yearly) as shown in the figure below.

Create Azure Backup Policy in the Azure portal
Create Azure Backup Policy in the Azure portal

After you’ve tailored all the backup policies based on your workloads, a new request came up from the upper management to update all the retention policies based on a new compliance policy that your company must adhere to.

For example, let’s say your company has a backup policy defined for each application to meet their regulatory compliance (E.g. Application A = daily for X number of days, weekly for X number of weeks, monthly for X number of months, and yearly for X number of years).

What about if you have 50 backup policies or more and you want to update the yearly retention from 1 to 10 years? Now, of course, you can log in to the Azure portal and update those backup policies. But this is not so efficient!

Automation to the rescue!

In this article, we will show you how to update the Azure Backup retention policy for daily, weekly, monthly, or yearly at scale using PowerShell.

Prerequisites

To follow this guide, you need to have the following:

1) Azure subscription – If you don’t have an Azure subscription, you can create a free one here.

2) Azure Resource Group obviously.

3) Azure Recovery Services Vault is already created.

4) The Azure PowerShell (Az module) is installed locally on your machine. You can use the following PowerShell command to install and update the “Az module”.

# Make sure you have the latest version of PowerShellGet installed
Install-Module -Name PowerShellGet -Force

# Install and update to the latest Az PowerShell module
Install-Module -Name Az -AllowClobber -Force

Assuming you have all the prerequisites in place, run the following PowerShell tool.

Update Azure Backup Protection Policy

You have a couple of options to run this tool, you can either use Azure Cloud Shell, Visual Studio Code, or the new Windows Terminal. The Script works with PowerShell 5.1 or PowerShell 7.* with the Az module installed.

.EXAMPLE

.\Update-AzBackupRetentionPolicy.ps1 -SubscriptionName [AzureSubscriptionName] `
     -$RSVaultName [RecoveryServicesVaultName] -WorkloadType [WorkloadType] `
     -UpdateDailyBackup [Yes] -UpdateWeeklyBackup [Yes] -UpdateMonthlyBackup [Yes] -UpdateYearlyBackup [Yes]

This example will update all the existing backup retention policies depending on the workload that you specified. For version 1.0 of this tool, you can update a backup policy for (Azure VM, Azure Files, or SQL Server in Azure VM) as workload type.

You need to specify the desired Azure Subscription and the Recovery Services Vault name where you want to update the policy. You can update the daily, weekly, monthly, or yearly retention policy by setting the switch to ‘YES‘.

When you run this tool, you need to authenticate with your Azure account assuming you have the right RBAC permissions to manage backup policies in your environment. Then you will be prompted to set the daily backup retention, the weekly backup retention, the monthly backup retention, or the yearly backup retention values based on what Azure backup support.

PowerShell Code

The complete tool is detailed below to automate the entire update process of the Azure backup policy retention:

<#
.SYNOPSIS
Update Azure Backup Retention Policy using PowerShell at scale.

.DESCRIPTION
Update Azure Backup Retention Policy using PowerShell for Azure VM, Azure Files, and SQL Server in Azure VM.

.NOTES
File Name : Update-AzBackupRetentionPolicy.ps1
Author    : Charbel Nemnom
Twitter   : @CharbelNemnom
Date      : 02-August-2022
Updated   : 02-August-2022
Version   : 1.0
Requires  : PowerShell Az and Az.RecoveryServices Module
Disclaimer: This script is provided "AS IS" with no warranties

.LINK
To provide feedback or for further assistance,
Please leave a comment below.

.EXAMPLE
.\Update-AzBackupProtectionPolicy.ps1 -SubscriptionName [AzureSubscriptionName] `
     -$RSVaultName [RecoveryServicesVaultName] -WorkloadType [WorkloadType] `
     -UpdateDailyBackup [Yes] -UpdateWeeklyBackup [Yes] -UpdateMonthlyBackup [Yes] -UpdateYearlyBackup [Yes]

This example will update all the existing backup retention policies depending on the workload that you specified.
For version 1.0 of this tool, you can update a backup policy for (Azure VM, Azure Files, or SQL Server in Azure VM) as workload type.
You need to specify the desired Azure subscription and the Recovery Services Vault name where you want to update the policy.
You can update the daily, weekly, monthly, or yearly retention policy by setting the switch to 'YES'.
In this example, I have updated all my existing yearly retention policies to 14 years without touching the daily, weekly, and monthly retentions.
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true, HelpMessage = 'Azure Subscription Name')]
    [ValidateNotNullOrEmpty()]
    [Alias('AzSubscriptionName')]
    [String]$SubscriptionName,

    [Parameter(Mandatory = $true, HelpMessage = 'Recovery Services Vault Name')]
    [ValidateNotNullOrEmpty()]
    [Alias('VaultName')]
    [String]$RSVaultName,    

    [ValidateSet("AzureVM", "AzureFiles", "MSSQL")]
    [String]$WorkloadType = 'AzureVM',

    [ValidateSet("Yes", "No")]
    [String]$UpdateDailyBackup = 'No',

    [ValidateSet("Yes", "No")]
    [String]$UpdateWeeklyBackup = 'No',

    [ValidateSet("Yes", "No")]
    [String]$UpdateMonthlyBackup = 'No',

    [ValidateSet("Yes", "No")]
    [String]$UpdateYearlyBackup = 'No'
)

#! Install Az Module If Needed
function Install-Module-If-Needed {
    param([string]$ModuleName)
 
    if (Get-Module -ListAvailable -Name $ModuleName) {
        Write-Host "Module '$($ModuleName)' already exists." -ForegroundColor Green
    } 
    else {
        Write-Host "Module '$($ModuleName)' does not exist, installing..." -ForegroundColor Yellow
        Install-Module $ModuleName -Force  -AllowClobber -ErrorAction Stop
        Write-Host "Module '$($ModuleName)' installed." -ForegroundColor Green
    }
}

Install-Module-If-Needed Az.Accounts

#! Login with Connect-AzAccount if NOT using Cloud Shell
#! Check Azure Connection
Try {
    Write-Verbose "Connecting to Azure Cloud..."
    Connect-AzAccount -ErrorAction Stop -WarningAction SilentlyContinue | Out-Null
}
Catch {
    Write-Warning "Cannot connect to Azure Cloud. Please check your credentials. Exiting!"
    Break
}

#! Set Azure Subscription Context
Try {
    Write-Verbose "Setting Azure Context - Subscription Name: $SubscriptionName..."
    $azSub = Get-AzSubscription -SubscriptionName $SubscriptionName
    Set-AzContext $azSub.id | Out-Null
}
Catch {
    Write-Warning "Cannot set Azure context. Please check your Azure subscription name. Exiting!"
    Break
}

#! Install Az RecoveryServices Module If Needed
Install-Module-If-Needed Az.RecoveryServices

If ($UpdateDailyBackup -eq "Yes") {
    If ($WorkloadType -eq "AzureVM" -or $WorkloadType -eq "MSSQL") {
        Do {
            [Int]$DailyRetention = Read-Host "Enter Daily backup retention for $WorkloadType - value must be between 7 and 9999"
        } while ($DailyRetention -lt 7 -or $DailyRetention -gt 9999)


        If ($WorkloadType -eq "AzureFiles") {
            Do {
                [Int]$DailyRetention = Read-Host "Enter Daily backup retention for $WorkloadType - value must be between 1 and 200"
            } while ($DailyRetention -lt 1 -or $DailyRetention -gt 200)
        }
    }
    
}

If ($UpdateWeeklyBackup -eq "Yes") {
    If ($WorkloadType -eq "AzureVM" -or $WorkloadType -eq "MSSQL") {
        Do {
            [Int]$WeeklyRetention = Read-Host "Enter Weekly backup retention for $WorkloadType - value must be between 1 and 5163"
        } while ($WeeklyRetention -lt 1 -or $WeeklyRetention -gt 5163)
    }

    If ($WorkloadType -eq "AzureFiles") {
        Do {
            [Int]$WeeklyRetention = Read-Host "Enter Weekly backup retention for $WorkloadType - value must be between 1 and 200"
        } while ($WeeklyRetention -lt 1 -or $WeeklyRetention -gt 200)
    }

}

If ($UpdateMonthlyBackup -eq "Yes") {
    If ($WorkloadType -eq "AzureVM" -or $WorkloadType -eq "MSSQL") {
        Do {
            [Int]$MonthlyRetention = Read-Host "Enter Monthly backup retention for $WorkloadType - value must be between 1 and 1188"
        } while ($MonthlyRetention -lt 1 -or $MonthlyRetention -gt 1188)
    }

    If ($WorkloadType -eq "AzureFiles") {
        Do {
            [Int]$MonthlyRetention = Read-Host "Enter Monthly backup retention for $WorkloadType - value must be between 1 and 200"
        } while ($MonthlyRetention -lt 1 -or $MonthlyRetention -gt 200)
    }
  
}

If ($UpdateYearlyBackup -eq "Yes") {
    If ($WorkloadType -eq "AzureVM" -or $WorkloadType -eq "MSSQL") {
        Do {
            [Int]$YearlyRetention = Read-Host "Enter Yearly backup retention for $WorkloadType - value must be between 1 and 99"
        } while ($YearlyRetention -lt 1 -or $YearlyRetention -gt 99)
    }

    If ($WorkloadType -eq "AzureFiles") {
        Do {
            [Int]$YearlyRetention = Read-Host "Enter Yearly backup retention for $WorkloadType - value must be between 1 and 10"
        } while ($YearlyRetention -lt 1 -or $YearlyRetention -gt 10)
    }
    
}

Try {
    Write-Verbose "Getting the existing Azure Recovery Services Vault..."
    $vault = Get-AzRecoveryServicesVault -Name $RSVaultName
    Write-Verbose "Setting Azure Recovery Services Vault Context..."
    Set-AzRecoveryServicesVaultContext -Vault $vault -ErrorAction Stop -WarningAction SilentlyContinue
}
Catch {
    Write-Warning "Cannot set Azure Recovery Services Vault Context. Please check your Azure Recovery Services Vault name. Exiting!"
    Break
}

Write-Verbose "Getting all existing Azure Backup Policies for Workload Type: $WorkloadType"
$backupPolicies = Get-AzRecoveryServicesBackupProtectionPolicy | Where-Object { $_.WorkloadType -eq $WorkloadType }

Write-Verbose "Getting a Base Backup Retention Policy object..."
$Pol = Get-AzRecoveryServicesBackupRetentionPolicyObject -WorkloadType $WorkloadType

foreach ($backupPolicy in $backupPolicies) {    
    If ($WorkloadType -eq "MSSQL") {
        Write-Verbose "Getting existing Retention Backup Policy for: $($BackupPolicy.Name)"   
        $RetPol = Get-AzRecoveryServicesBackupProtectionPolicy -Name $BackupPolicy.Name   
    }
    Else {
        Write-Verbose "Getting existing Retention Backup Policy for: $($BackupPolicy.Name)"   
        $RetPol = (Get-AzRecoveryServicesBackupProtectionPolicy -Name $BackupPolicy.Name).RetentionPolicy
    }

    If ($UpdateDailyBackup -eq "Yes") { 
        Write-Verbose "Updating Daily Retention for $($BackupPolicy.Name) to $DailyRetention days..."
        $RetPol.DailySchedule.DurationCountInDays = $DailyRetention
    }

    If ($UpdateWeeklyBackup -eq "Yes" -and $WorkloadType -eq "MSSQL") { 
        Write-Verbose "Updating Weekly Retention for $($BackupPolicy.Name) to $WeeklyRetention weeks..."        
        $Pol.FullBackupRetentionPolicy = $RetPol.FullBackupRetentionPolicy
        $Pol.DifferentialBackupRetentionPolicy = $RetPol.DifferentialBackupRetentionPolicy
        $Pol.LogBackupRetentionPolicy = $RetPol.LogBackupRetentionPolicy        
        $Pol.FullBackupRetentionPolicy.WeeklySchedule.DurationCountInWeeks = $WeeklyRetention        
    }
    Elseif ($UpdateWeeklyBackup -eq "Yes") {    
        Write-Verbose "Updating Weekly Retention for $($BackupPolicy.Name) to $WeeklyRetention weeks..."
        $RetPol.WeeklySchedule = $Pol.WeeklySchedule
        $RetPol.IsWeeklyScheduleEnabled = $true
        $RetPol.WeeklySchedule.DurationCountInWeeks = $WeeklyRetention
    }

    If ($UpdateMonthlyBackup -eq "Yes" -and $WorkloadType -eq "MSSQL") {
        Write-Verbose "Updating Monthly Retention for $($BackupPolicy.Name) to $MonthlyRetention months..."
        $Pol.FullBackupRetentionPolicy = $RetPol.FullBackupRetentionPolicy
        $Pol.DifferentialBackupRetentionPolicy = $RetPol.DifferentialBackupRetentionPolicy
        $Pol.LogBackupRetentionPolicy = $RetPol.LogBackupRetentionPolicy 
        $Pol.FullBackupRetentionPolicy.MonthlySchedule.DurationCountInMonths = $MonthlyRetention
    }
    Elseif ($UpdateMonthlyBackup -eq "Yes") {
        Write-Verbose "Updating Monthly Retention for $($BackupPolicy.Name) to $MonthlyRetention months..."
        $RetPol.MonthlySchedule = $Pol.MonthlySchedule
        $RetPol.IsMonthlyScheduleEnabled = $true
        $RetPol.MonthlySchedule.DurationCountInMonths = $MonthlyRetention
    }

    If ($UpdateYearlyBackup -eq "Yes" -and $WorkloadType -eq "MSSQL") {
        Write-Verbose "Updating Yearly Retention for $($BackupPolicy.Name) to $YearlyRetention years..."      
        $Pol.FullBackupRetentionPolicy = $RetPol.FullBackupRetentionPolicy
        $Pol.DifferentialBackupRetentionPolicy = $RetPol.DifferentialBackupRetentionPolicy
        $Pol.LogBackupRetentionPolicy = $RetPol.LogBackupRetentionPolicy 
        $Pol.FullBackupRetentionPolicy.YearlySchedule.DurationCountInYears = $YearlyRetention
    }
    ElseIf ($UpdateYearlyBackup -eq "Yes") {
        Write-Verbose "Updating Yearly Retention for $($BackupPolicy.Name) to $YearlyRetention years..."
        $RetPol.YearlySchedule = $Pol.YearlySchedule
        $RetPol.IsYearlyScheduleEnabled = $true
        $RetPol.YearlySchedule.DurationCountInYears = $YearlyRetention
    }
    
    If ($WorkloadType -eq "MSSQL") {
        Write-Verbose "Updating Azure Backup Retention Policy Name: $($BackupPolicy.Name)"
        Set-AzRecoveryServicesBackupProtectionPolicy -Policy $BackupPolicy -RetentionPolicy $Pol | Out-Null
    }
    Else {
        Write-Verbose "Updating Azure Backup Retention Policy Name: $($BackupPolicy.Name)"
        Set-AzRecoveryServicesBackupProtectionPolicy -Policy $BackupPolicy -RetentionPolicy $RetPol | Out-Null
    }
    
}

Here is how to run this tool in action:

Modify Azure Backup Policy at Scale using PowerShell
Modify Azure Backup Policy at Scale using PowerShell

If you look back in the Azure portal under your Recovery Services Vault, you will see the Azure Backup retention policy is updated successfully with the chosen retention range.

That’s it there you have it. Happy updating Azure Backup policy retention!

Summary

In this article, we showed you how to automate the update process and modify all Azure Backup retention policies using PowerShell. Now, of course, you can use Azure CLI, ARM Templates, Bicep, or Terraform to do the same, however, I prefer to use Azure PowerShell.

This is version 1.0, if you have any feedback or changes that everyone should receive, please feel free to leave a comment below.

> Learn more about how to enable Azure Backup on VMs using Azure Policy.

> Learn more about protecting an Azure Trusted Launch VM with Azure Backup.

Do you want to explore the Azure Backup service in a deeper way, diving into the finer details of how things work, and helping people understand where it differs from what we traditionally used to do in the backup world? I highly recommend checking Azure Backup Deep Dive – Free Whitepaper.

__
Thank you for reading my blog.

If you have any questions or feedback, please leave a comment.

-Charbel Nemnom-

Photo of author
Author
Charbel Nemnom
Charbel Nemnom is a Senior Cloud Architect, Swiss Certified ICT Security Expert, Certified Cloud Security Professional (CCSP), Certified Information Security Manager (CISM), Microsoft Most Valuable Professional (MVP), and Microsoft Certified Trainer (MCT). He has over 20 years of broad IT experience serving on and guiding technical teams to optimize the performance of mission-critical enterprise systems with extensive practical knowledge of complex systems build, network design, business continuity, and cloud security.

Related Posts

Previous

How To Update Microsoft Office On Mac (Easily)

Which Security Protocol Does Secure File Transfer (SFTP) Use To Transfer Data?

Next

Let me know what you think, or ask a question...

error: Alert: The content of this website is copyrighted from being plagiarized! You can copy from the 'Code Blocks' in 'Black' by selecting the Code. Thank You!