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 Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s