Azure Files 10 years retention

As per this blog post, you can now backup Azure Files with a retention of 10 years!

  • Microsoft have enabled on-demand backups that can retain your snapshots for 10 years using PowerShell
  • Backup for Azure file shares offers the ability to configure policies with retention up to 180 days. However, using the “On-demand backup” option in PowerShell, you can retain a recovery point even for 10 years!
  • You can have up to 200 Snapshots for a file share at any point in time

A couple of points to consider at the time of writing.

  • Currently there isn’t a way to get the retention period of a snapshot from PowerShell or portal
  • There is no PowerShell support currently for listing files in a recovery point

However, all the backup components & dependancies look something like the below:

Setting this up, running through this piece by piece using PowerShell – first things first, you’ll need to sign into Azure:

######################################################
# Sign into Azure
######################################################
Connect-AzAccount
Get-AzSubscription | ? {$_.Name -match 'Internal Consumption'} | Select-AzSubscription

The next part is to set some important variables i.e the retention in number of days, up to 10 years.

You’ll also need a Backup Policy name, if you don’t currently have a backup policy, this will create one for you.

######################################################
# Preliminary steps
######################################################
# Set some variables
[int]$RetentionDays = '300'
$currentDate = Get-Date
$RetailTill = $currentDate.AddDays($RetentionDays)

$BackupPolicyName = 'NewAFSPolicy'
$StorageAccountName = 'marcmedia'
$AzureFilesShareName = 'media'
$RecoveryVaultName = 'testvault'

Set the Recovery Services Vault Context:

# Set the vault context
Get-AzRecoveryServicesVault -Name $RecoveryVaultName | Set-AzRecoveryServicesVaultContext

Next you setup a backup policy by leveraging a
Retention Policy Object and Schedule Policy Object.

Both Get-AzRecoveryServicesBackupSchedulePolicyObject and Get-AzureRmRecoveryServicesBackupRetentionPolicyObject cmdlet gets a base Retention Policy Object or Schedule Policy Object. This object is not persisted in the system. It is a temporary object that you can manipulate, you use them both with the New-AzureRmRecoveryServicesBackupProtectionPolicy cmdlet to create a new backup policy.

######################################################
# Configure backup for an Azure file share
######################################################
<#
Create a generic protection policy - $BackupPolicyName - if it's not already created
This takes a daily backup and retains it for 30 days
#>
$afsPol = Get-AzRecoveryServicesBackupProtectionPolicy `
-WorkloadType "AzureFiles" | Where-Object {$_.name -eq $BackupPolicyName} -ErrorAction SilentlyContinue
if(!($afsPol).Name){
    $schPol = Get-AzRecoveryServicesBackupSchedulePolicyObject -WorkloadType "AzureFiles"
    $retPol = Get-AzRecoveryServicesBackupRetentionPolicyObject -WorkloadType "AzureFiles"
    New-AzRecoveryServicesBackupProtectionPolicy -Name $BackupPolicyName `
    -WorkloadType "AzureFiles" -RetentionPolicy $retPol -SchedulePolicy $schPol
}

Register the Azure Storage account as a container against the Recovery Vault. A container that is registered to an Azure Recovery Services vault can have one or more items that can be protected. For Azure virtual machines, there can be only one backup item in the virtual machine container being the virtual machine itself. As for Azure Files, there can be multiple backup items per container, being multiple Azure Files Shares per Storage Account.

The Enable-AzRecoveryServicesBackupProtection cmdlet below sets Azure Backup protection policy on a backup item. Setting the vault context by using the Set-AzRecoveryServicesVaultContext cmdlet before ensures that this the backup item is registered against the correct Recovery Services Vault.

Note the parameters:
Name | Specifies the name of the Backup item (item)
StorageAccountName | Azure file share storage account name (container)

<#
Enable protection for an Azure Files Share - if it's not already enabled
#>
$afsContainer = Get-AzRecoveryServicesBackupContainer `
-FriendlyName $StorageAccountName -ContainerType AzureStorage -ErrorAction SilentlyContinue
$afsBkpItem = Get-AzRecoveryServicesBackupItem -Container $afsContainer `
-WorkloadType "AzureFiles" -Name $AzureFilesShareName
if(!($afsBkpItem)){
    $afsPol = Get-AzRecoveryServicesBackupProtectionPolicy -WorkloadType "AzureFiles" | Where-Object {$_.name -eq $BackupPolicyName}
    Enable-AzRecoveryServicesBackupProtection -StorageAccountName $StorageAccountName `
        -Name $AzureFilesShareName -Policy $afsPol
}

The last step is to trigger the actual backup. You get the container (Storage Account) and the backup item (Azure Files Share) which should be already registered to a recovery services vault, then you kick off a backup while applying the custom retention – which you configured above in one of the variables.

######################################################
# On-Demand Backup
######################################################
<#
# Trigger an on-demand backup
#>
$afsContainer = Get-AzRecoveryServicesBackupContainer -FriendlyName $StorageAccountName -ContainerType AzureStorage
$afsBkpItem = Get-AzRecoveryServicesBackupItem -Container $afsContainer `
-WorkloadType "AzureFiles" -Name $AzureFilesShareName
$job = Backup-AzRecoveryServicesBackupItem -Item $afsBkpItem -ExpiryDateTimeUTC $RetailTill

The rest of the script has other items, and I have shared the full script below derived from GIST.

<#
Written with version 1.3.0 of the Az PowerShell Module
Run Get-InstalledModule to check installed modules
Install PowerShell Core 6 https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows?view=powershell-6
The Az PowerShell Module is available from here https://github.com/Azure/azure-powershell/releases/tag/v1.4.0-February2019
… or run: Install-Module -Name Az -RequiredVersion 1.4.0 -AllowClobber
Migration instructions Azure.RM to Az – https://azure.microsoft.com/en-au/blog/how-to-migrate-from-azurerm-to-az-in-azure-powershell/
#>
<#
https://github.com/Azure-Samples/Use-PowerShell-for-long-term-retention-of-Azure-Files-Backup
#>
######################################################
# Sign into Azure
######################################################
Connect-AzAccount
Get-AzSubscription | ? {$_.Name -match 'Internal Consumption'} | Select-AzSubscription
######################################################
# Preliminary steps
######################################################
# Set some variables
[int]$RetentionDays = '300'
$currentDate = Get-Date
$RetailTill = $currentDate.AddDays($RetentionDays)
$BackupPolicyName = 'NewAFSPolicy'
$StorageAccountName = 'marcmedia'
$AzureFilesShareName = 'aidem2019'
$RecoveryVaultName = 'testvault'
# Set the vault context
Get-AzRecoveryServicesVault -Name $RecoveryVaultName | Set-AzRecoveryServicesVaultContext
######################################################
# Configure backup for an Azure file share
######################################################
<#
Create a generic protection policy – $BackupPolicyName – if it's not already created
This takes a daily backup and retains it for 30 days
#>
$afsPol = Get-AzRecoveryServicesBackupProtectionPolicy `
-WorkloadType "AzureFiles" | Where-Object {$_.name -eq $BackupPolicyName} -ErrorAction SilentlyContinue
if(!($afsPol).Name){
$schPol = Get-AzRecoveryServicesBackupSchedulePolicyObject -WorkloadType "AzureFiles"
$retPol = Get-AzRecoveryServicesBackupRetentionPolicyObject -WorkloadType "AzureFiles"
New-AzRecoveryServicesBackupProtectionPolicy -Name $BackupPolicyName `
-WorkloadType "AzureFiles" -RetentionPolicy $retPol -SchedulePolicy $schPol
}
<#
Enable protection for an Azure Files Share – if it's not already enabled
#>
# Backup Containers are things like a storage account or a virtual machine – AzureVM, Windows, AzureSQL, AzureStorage
$afsContainer = Get-AzRecoveryServicesBackupContainer `
-FriendlyName $StorageAccountName -ContainerType AzureStorage -ErrorAction SilentlyContinue
# Backup items are things like Azure Files Shares inside of a Storage Account container, or VMs inside of a VM container
$afsBkpItem = Get-AzRecoveryServicesBackupItem -Container $afsContainer `
-WorkloadType "AzureFiles" -Name $AzureFilesShareName
if(!($afsBkpItem)){
$afsPol = Get-AzRecoveryServicesBackupProtectionPolicy -WorkloadType "AzureFiles" | Where-Object {$_.name -eq $BackupPolicyName}
Enable-AzRecoveryServicesBackupProtection -StorageAccountName $StorageAccountName `
-Name $AzureFilesShareName -Policy $afsPol
}
Enable-AzRecoveryServicesBackupProtection –
###############################################################################################################
############################# Unregister a backup container – only if you need to #############################
###############################################################################################################
<#
# Unregister a backup container
#>
Get-AzRecoveryServicesBackupContainer -ContainerType AzureStorage
$afsContainer = Get-AzRecoveryServicesBackupContainer -FriendlyName 'Name' -ContainerType AzureStorage
Unregister-AzRecoveryServicesBackupContainer -Container $afsContainer
######################################################
# On-Demand Backup
######################################################
<#
# Trigger an on-demand backup
#>
$afsContainer = Get-AzRecoveryServicesBackupContainer -FriendlyName $StorageAccountName -ContainerType AzureStorage
$afsBkpItem = Get-AzRecoveryServicesBackupItem -Container $afsContainer `
-WorkloadType "AzureFiles" -Name $AzureFilesShareName
$job = Backup-AzRecoveryServicesBackupItem -Item $afsBkpItem -ExpiryDateTimeUTC $RetailTill
######################################################
# Check Recovery Points
######################################################
<#
Restore Azure file shares to an alternate location
#>
# Fetch recovery points
$afsContainer = (Get-AzRecoveryServicesBackupContainer -FriendlyName $StorageAccountName -ContainerType AzureStorage)[0]
$afsBkpItem = Get-AzRecoveryServicesBackupItem -Container $afsContainer `
-WorkloadType "AzureFiles" -Name $AzureFilesShareName
if($afsBkpItem -ne $null){
$startDate = (Get-Date).AddDays(-7)
$endDate = Get-Date
$rp = Get-AzRecoveryServicesBackupRecoveryPoint -Item $afsBkpItem `
-StartDate $startdate.ToUniversalTime() -EndDate $enddate.ToUniversalTime()
$rp[0] | fl *
}
######################################################
# Restore Azure file shares and Azure files
######################################################
# Restore an Azure file share
Restore-AzRecoveryServicesBackupItem -RecoveryPoint $rp[0] -TargetStorageAccountName $StorageAccountName `
-TargetFileShareName "DestAFS" -TargetFolder "testAzureFS_restored" -ResolveConflict Overwrite
# Restore an Azure file
Restore-AzRecoveryServicesBackupItem -RecoveryPoint $rp[0] -TargetStorageAccountName $StorageAccountName `
-TargetFileShareName "DestAFS" -TargetFolder "testAzureFS_restored" `
-SourceFileType File -SourceFilePath "TestDir/TestDoc.docx" -ResolveConflict Overwrite
<#
Restore Azure file shares to the original location
#>
# Overwrite an Azure file share
Restore-AzRecoveryServicesBackupItem -RecoveryPoint $rp[0] -ResolveConflict Overwrite
# Overwrite an Azure file
Restore-AzRecoveryServicesBackupItem -RecoveryPoint $rp[0] -SourceFileType File `
-SourceFilePath "TestDir/TestDoc.docx" -ResolveConflict Overwrite

Leave a comment