Using blob snapshots with PowerShell


Sometime ago, I had a customer who asked me the way to create a blob snapshot of an Azure VM. The process for create a blob snapshot was clear for the customer and you can read the next blog as a reference:

https://azure.microsoft.com/en-us/documentation/articles/storage-powershell-guide-full/#how-to-manage-azure-blob-snapshots

As you read in the article, you can create, list, copy and delete a blob snapshot, but how can you get a particular snapshot that was taken before and not the one you just created?

First, please read the next reference blog to have in mind some consideration of the blob snapshots.

https://azure.microsoft.com/en-us/documentation/articles/storage-blob-snapshots

Now, let’s go to the code.

NOTE: Check that you have PowerShell already installed, details here.

Login to your Azure Subscription.

=============================================

  1. Open a PowerShell session with Admin rights.
  2. Run the command : Login-AzureRmAccount
  3. Provide the credentials that you usually use to Login to the Azure Portal.

 

To create a snapshot.

=============================================

  1. Define the storage account and the context.
1
2
3
4
$StorageAccountName = "yourstorageaccount"
$StorageAccountKey = "Storage key for yourstorageaccount ends with =="
$ContainerName = "yourcontainername"
$BlobName = "yourblobname" 
  1. Create the context.
1
$Ctx = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey 
  1. Get a reference to a blob.
1
$blob = Get-AzureStorageBlob -Context $Ctx -Container $ContainerName -Blob $BlobName 
  1. Create a blob snapshot.
1
$snap = $blob.ICloudBlob.CreateSnapshot()

 

With this procedure you can create a snapshot at any time for the $BlobName defined.

Consider that the name will be the same as the original blob, but at the time the blob snapshot is created, there is a snapshotTime property that includes the precise date/time when the blob snapshot was created. We will use the snapshotTime property to determinate and select later, the blob snapshot that you want to copy and/or to be used for you to promote.

 

Retrieve the blob snapshot list.

=============================================

  1. List the blob snapshots.
1
$ListBlob = Get-AzureStorageBlob Context $Ctx -Prefix $BlobName -Container $ContainerName | Where-Object {$_.ICloudBlob.IsSnapshot -and $_.Name -eq $BlobName -and $_.SnapshotTime -ne $null }

 

The above command will provide all the blob snapshots associated with the $BlobName.

If we check the $ListBlob variable, it will show us the list of blob snapshots, and in one of the columns, we can see the snapshotTime column displaying the time the snapshot was taken (this is in UTC Time zone).

listSnapshots

 

Copy a particular/specific blob snapshot.

=============================================

  1. Define the variables.
1
2
$DestContainerName = "yourdestcontainername"
$DestBlobName = "CopyBlobName"
  1. Create a table to list the blob snapshots you have (this will let you select the item and the snapshotTime property from this table, so later we can get the snapshot based on the snapshotTime property).
1
$ListBlob | Format-Table -AutoSize

In the image below, you can see all the blob snapshots have the name "juliocotest2016123225918.vhd" and the way you can identify when the blob snapshot was taken is by checking the snapshotTime property.

listSnapshots2

  1. Using the table above, you can select the blob snapshot you want to be copied by using the snapshotTime property, so, let’s said you want to copy the snapshot that was taken last “2/25/2016 6:01:30 AM +00:00”. So, you will use and select the SnapshotTime property for that item “3” (Note: Consider that "Item" is the item from the table to be selected based on the SnapshotTime property that you want to select/copy).
1
$SnapshotTime = $ListBlob[Item] | select -ExpandProperty SnapshotTime
  1. Now, select the blob snapshot you want to restore based on the snapshotTime property we got from previous step.
1
$RestorePoint = $ListBlob | where { $_.SnapshotTime -eq $SnapshotTime }
  1. Now, let’s convert the blob selected to a CloudBlob type.
1
$snapshot = [Microsoft.WindowsAzure.Storage.Blob.CloudBlob] $RestorePoint[0].ICloudBlob
  1. Finally, you can now copy the blob snapshot to another container.
1
Start-AzureStorageBlobCopy Context $Ctx -ICloudBlob $snapshot -DestBlob $DestBlobName -DestContainer $DestContainerName

As you can see in the image below, I was able to copy that particular snapshot into my “snapshots” container.

listSnapshot3

 

Now, I used Azure Storage Explorer, to check the blob.

Here is a screenshot showing the blob I had before copied the blob snapshot, in my “snapshots” container.

explorer1

And in the next screenshot you can see the “recovery.vhd” page blob that was copied from the snapshot list.

explorer2

Now, just to end this blog, I would like to show you the way to delete a series of blob snapshots based on the time they were taken (yes, using the snapshotTime property). To do that, you need to list again the blob snapshots you have.

 

Retrieve the snapshots list.

=============================================

  1. List the snapshots of a blob.
1
2
$blob = Get-AzureStorageContainer -Context $Ctx -Name $ContainerName
$ListOfBlobs = $blob.CloudBlobContainer.ListBlobs($BlobName, $true, "Snapshots")

The above command will provide all the snapshot associated with the $BlobName

listSnapshot4

 

Declare the min and max dates (to be removed).

=============================================

  1. Declare minimum date, example:
1
$minDate = [datetime]"01/23/2016 9:00 AM"
  1. Declare maximum date, example:
1
$maxDate = [datetime]"02/24/2016 9:00 PM"

The above is telling you that you want to delete the blob snapshots from $minDate ("01/23/2016 9:00 AM") to $maxDate ("02/24/2016 9:00 PM").

 

Delete the snapshot of a blob.

=============================================

  1. For this, I did a foreach iteration to validate first if the blob is a snapshot and then to validate if it is in the range of dates I defined in previous step.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
foreach ($CloudBlockBlob in $ListOfBlobs)
{
  if ($CloudBlockBlob.IsSnapshot)
  {
    if ($CloudBlockBlob.SnapshotTime -le $maxDate -and $CloudBlockBlob.SnapshotTime -ge $minDate )
    {
      $CloudBlockBlob.Delete()
    }
  }
}

Finally, you can list again the snapshot list and you will see that you already deleted the ones for the dates you defined.

listSnapshot5

Happy coding !!

Comments (4)

  1. Do I need to stop the VM to take a snapshot or restore it's OS or data disc?

    1. Hello Vladimir,
      You do not need to stop the VM to take the snapshot, however, to restore the OS, if the VM is running, then the VHD will have a lease and this will prevent access to that blob. You will need to remove first the VHD from the running VM and then you can perform the restore operation.

  2. Adam Bird says:

    Thanks very much for this information 🙂

Skip to main content