Victor protects a file share, takes a recovery point, deletes the file, and watches the restore job return it.
Run one step, then check it
Read the step before copying. Bash commands belong in Git Bash on Windows or Azure Cloud Shell set to Bash; PowerShell uses different syntax. A JSON, YAML, Bicep or application-code example belongs in the named file, not directly at the terminal prompt. Follow any shell-specific instructions below.
Keep the same terminal open so earlier variables remain available. Copy one complete command block without the terminal's $ prompt. A backslash continues a command onto the next line. If Bash shows a lone >, it is waiting for the rest of a quote, command or file block. Finish the complete block; if the paste was incomplete, press Ctrl+C and copy it again. Do not paste the next step into an unfinished command.
A line such as RG="training-group" stores a value without printing it. Output captured with $(...) is also stored; a blank screen alone does not prove failure. A sleep deliberately waits, and -o none suppresses normal output. Wait for your normal prompt, then run the step's checkpoint. After an error, stop and keep the exact command and message; later steps cannot repair a missing resource. Never share passwords, access tokens or secret values in a screenshot.
Backup vs. redundancy vs. a snapshot you took once
Storage redundancy (LRS/ZRS/GRS) keeps extra copies of your data against a hardware failure — but it faithfully replicates a deletion or a ransomware encryption too, because it does not know the change was a mistake. A one-off snapshot is better, but nobody remembers to take them and nobody knows when the last one was. Azure Backup is the discipline in between: a policy takes recovery points on a schedule and keeps them for a set retention, in a Recovery Services vault that lives apart from the data it protects. This lab runs the whole loop on an Azure Files share — the cheapest, fastest workload that still teaches vault, policy, recovery point, and, the part that actually matters, the restore.
A backup you never restore is a rumour.
You need a free Azure account and the Azure CLI (az), signed in with az login. First time? The 15-minute Set up your machine page covers the account, the installs, and sign-in. Prefer zero installs? Run everything in Azure Cloud Shell (Bash), preinstalled and already signed in.
This is not strictly free tier: protecting a file share carries a small protected-instance charge plus a few pennies of snapshot storage. Run start-to-finish and tear down the same day and it costs roughly a few cents — but if you leave it running, that becomes a few dollars a month. The teardown section removes everything. Pairs with Class 36d — Azure Backup.
A file share worth protecting
Create a storage account, a small file share, and drop one file in it — the thing you will later "lose."
Commands inside $(...) save their output in a variable. Check the printed identifier or the checkpoint before continuing. Normal command output is suppressed here. Use the checkpoint to verify the resource or result; an error still needs investigation.
# Windows/Git Bash: stop it mangling resource-id arguments (harmless on macOS/Linux) export MSYS_NO_PATHCONV=1 SUFFIX=$RANDOM RG="campux-lab-dr-rg" LOCATION="eastus" SA="campuxdr$SUFFIX" # 3-24 lowercase alphanumeric SHARE="campuxfiles" VAULT="campux-dr-vault" POLICY="campux-afs-policy" az group create --name "$RG" --location "$LOCATION" -o table az storage account create --name "$SA" --resource-group "$RG" \ --location "$LOCATION" --sku Standard_LRS --kind StorageV2 -o none az storage share-rm create --resource-group "$RG" \ --storage-account "$SA" --name "$SHARE" --quota 1 -o none # upload one throwaway file, using an account key KEY=$(az storage account keys list -g "$RG" -n "$SA" --query "[0].value" -o tsv) echo "The quarterly numbers nobody wants to lose." > payroll.csv az storage file upload --account-name "$SA" --account-key "$KEY" \ --share-name "$SHARE" --source payroll.csv -o none
az storage file list --account-name "$SA" --account-key "$KEY" --share-name "$SHARE" -o table shows payroll.csv.A vault and a backup policy
The vault holds recovery points apart from the share. Set its redundancy while it is empty (you cannot change it once backups exist), then build a file-share policy from the built-in default template so you do not have to hand-write the schedule JSON.
az backup vault create --resource-group "$RG" --name "$VAULT" \ --location "$LOCATION" -o table # cheaper local redundancy for a throwaway lab — must run before any backup item exists az backup vault backup-properties set --name "$VAULT" --resource-group "$RG" \ --backup-storage-redundancy LocallyRedundant # a new vault has no file-share policy to copy, so write one: back up daily, keep 30 days cat > afs-policy.json <<'EOF' { "properties": { "backupManagementType": "AzureStorage", "workLoadType": "AzureFileShare", "schedulePolicy": { "schedulePolicyType": "SimpleSchedulePolicy", "scheduleRunFrequency": "Daily", "scheduleRunTimes": ["2026-01-01T19:30:00Z"] }, "retentionPolicy": { "retentionPolicyType": "LongTermRetentionPolicy", "dailySchedule": { "retentionTimes": ["2026-01-01T19:30:00Z"], "retentionDuration": { "count": 30, "durationType": "Days" } } }, "timeZone": "UTC" } } EOF az backup policy create --resource-group "$RG" --vault-name "$VAULT" \ --policy afs-policy.json --name "$POLICY" \ --backup-management-type AzureStorage
az backup policy list --resource-group "$RG" --vault-name "$VAULT" --backup-management-type AzureStorage -o table lists campux-afs-policy.Protect the share, then take a recovery point
Enable protection, then trigger an on-demand backup rather than waiting for the schedule — you want a recovery point in hand and you want to watch a job finish.
Commands inside $(...) save their output in a variable. Check the printed identifier or the checkpoint before continuing.
az backup protection enable-for-azurefileshare \
--vault-name "$VAULT" --resource-group "$RG" \
--policy-name "$POLICY" --storage-account "$SA" \
--azure-file-share "$SHARE" -o table
# capture the exact container + item names the later commands need
CONTAINER=$(az backup container list --resource-group "$RG" --vault-name "$VAULT" \
--backup-management-type azurestorage --query "[0].name" -o tsv)
ITEM=$(az backup item list --resource-group "$RG" --vault-name "$VAULT" \
--backup-management-type azurestorage --query "[0].name" -o tsv)
az backup protection backup-now \
--vault-name "$VAULT" --resource-group "$RG" \
--container-name "$CONTAINER" --item-name "$ITEM" \
--retain-until "$(date -u -d '+30 days' +%d-%m-%Y)" -o table
az backup job list --resource-group "$RG" --vault-name "$VAULT" -o table. When the Backup operation reads Completed, you hold a real recovery point. (A file-share backup usually finishes in a minute or two.)Stage the disaster: delete the file
Now lose it — the deleted spreadsheet, the fat-fingered delete, the everyday incident that item-level restore exists for.
az storage file delete --account-name "$SA" --account-key "$KEY" \
--share-name "$SHARE" --path payroll.csv
az storage file exists --account-name "$SA" --account-key "$KEY" \
--share-name "$SHARE" --path payroll.csv --query exists # -> false
exists query returns false. The live share no longer has the file — but the vault still does.Restore it from the vault
Find the recovery point and restore just that one file back to its original location.
Commands inside $(...) save their output in a variable. Check the printed identifier or the checkpoint before continuing.
# the newest recovery point
RP=$(az backup recoverypoint list --vault-name "$VAULT" --resource-group "$RG" \
--container-name "$CONTAINER" --item-name "$ITEM" \
--backup-management-type azurestorage --workload-type azurefileshare \
--query "[0].name" -o tsv)
az backup restore restore-azurefiles \
--vault-name "$VAULT" --resource-group "$RG" --rp-name "$RP" \
--container-name "$CONTAINER" --item-name "$ITEM" \
--restore-mode originallocation \
--source-file-type file --source-file-path "payroll.csv" \
--resolve-conflict overwrite -o table
Restore job to read Completed in az backup job list ... -o table, then re-run the exists check: az storage file exists --account-name "$SA" --account-key "$KEY" --share-name "$SHARE" --path payroll.csv --query exists now returns true. The identical share that was missing the file has it back — the only thing that changed was a restore job. That is the entire lesson.Tear it down (mind the lock and soft delete)
Two things Azure Backup did while you were not looking. It put a delete lock called AzureBackupProtectionLock on the storage account, so the group cannot be deleted until that lock goes. And soft delete is always on for new vaults: when you delete the backup data, the recovery point is kept, free, for 14 days, and the vault cannot be deleted while it holds one. So the honest teardown removes everything except the empty vault today, and the vault after the hold ends.
az backup protection disable \ --vault-name "$VAULT" --resource-group "$RG" \ --container-name "$CONTAINER" --item-name "$ITEM" \ --backup-management-type azurestorage --workload-type azurefileshare \ --delete-backup-data true --yes -o table # remove the lock Azure Backup added, then delete what can be deleted today for LOCK in $(az lock list --resource-group "$RG" --query "[].id" -o tsv); do az lock delete --ids "$LOCK" done az storage account delete --name "$SA" --resource-group "$RG" --yes az resource list --resource-group "$RG" --query "[].name" -o tsv # -> only campux-dr-vault
az group delete --name "$RG" --yes and az group exists --name "$RG" (expect false). If the delete still refuses, the hold has not ended; check again in a day.az backup vault backup-properties set --soft-delete-feature-state Disable may return without an error, but on a vault created today the setting stays AlwaysON; check with az backup vault backup-properties show and you will see. We tried it in October 2026. The 14-day hold is the feature that saves a company from a malicious administrator; waiting it out is the lesson.
What you can now honestly claim
You created a Recovery Services vault, built a backup policy, protected an Azure Files share, took an on-demand recovery point, and — the part most engineers never do — actually restored, returning a deleted file from the vault to its original place. You know a vault stores recovery points apart from what they protect, that a policy is a schedule plus a retention, and that soft delete guards the backups themselves (and blocks a careless teardown). The same loop scales up: a full share restore, a full VM restore, or a cross-region restore where the vault is GRS. The one DR step this lab deliberately skips is an Azure Site Recovery test failover — it needs replicated VMs and target-region compute, so Class 36e — Azure Site Recovery covers it as a walkthrough rather than a paid exercise.