Here's the code to go with Zhaoxing Lu's logic. The approach is to first list the snapshots of the source blob, create blob in the destination from the snapshots and take snapshots of that blob. Finally you would copy the base blob into target blob.
static void CopyBlobAndSnapshots()
{
var sourceAccountName = "<source-account-name>";
var sourceAccountKey = "<source-account-key>";
var sourceContainerName = "<source-container-name>";
var targetAccountName = "<target-account-name>";
var targetAccountKey = "<target-account-key>";
var targetContainerName = "<target-container-name>";
var blobName = "<source-blob-name>";
var sourceAccount = new CloudStorageAccount(new StorageCredentials(sourceAccountName, sourceAccountKey), true);
var targetAccount = new CloudStorageAccount(new StorageCredentials(targetAccountName, targetAccountKey), true);
var sourceBlobClient = sourceAccount.CreateCloudBlobClient();
var sourceContainer = sourceBlobClient.GetContainerReference(sourceContainerName);
var sourceBlob = sourceContainer.GetBlockBlobReference(blobName);
var targetBlobClient = targetAccount.CreateCloudBlobClient();
var targetContainer = targetBlobClient.GetContainerReference(targetContainerName);
targetContainer.CreateIfNotExists();
//Create a SAS Token on source blob with read permissions that is valid for 2 weeks.
var sasToken = sourceBlob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessExpiryTime = new DateTimeOffset(DateTime.UtcNow.AddDays(14))
});
//List blob snapshots first
var baseBlobAndSnapshots = sourceContainer.ListBlobs(blobName, true, BlobListingDetails.Snapshots).ToList();
//Since the list contains both base blob and snapshots, we should remove the base blob from this list.
var blobSnapshots = baseBlobAndSnapshots.Where(b => ((CloudBlockBlob)b).SnapshotTime != null).ToList();
//Now we should arrange them in reverse chronological order
blobSnapshots.Reverse();
CloudBlockBlob targetBlob = null;
string sourceBlobUrl = string.Empty;
foreach (var blob in blobSnapshots)
{
var blockBlob = (CloudBlockBlob) blob;
Console.WriteLine("Copying blob snapshot. Snapshot date/time = " + blockBlob.SnapshotTime);
sourceBlobUrl = string.Format("{0}&{1}", blockBlob.SnapshotQualifiedUri, sasToken.Substring(1));
targetBlob = targetContainer.GetBlockBlobReference(blobName);
targetBlob.StartCopy(new Uri(sourceBlobUrl));
//Check the status;
targetBlob.FetchAttributes();
do
{
var copyState = targetBlob.CopyState;
if (copyState.Status == CopyStatus.Pending)
{
Thread.Sleep(1000);//Copy not completed. Wait for it to complete.
targetBlob.FetchAttributes();
}
else
{
break;
}
}
while (true);
Console.WriteLine("Copying blob snapshot complete. Snapshot date/time = " + blockBlob.SnapshotTime);
Console.WriteLine("----------------------------");
//Now take the blob snapshot
Console.WriteLine("Taking blob snapshot....");
targetBlob.Snapshot();
Console.WriteLine("Blob snapshot taken....");
Console.WriteLine("----------------------------");
}
Console.WriteLine("Copying base blob.");
sourceBlobUrl = string.Format("{0}{1}", sourceBlob.Uri, sasToken);
targetBlob = targetContainer.GetBlockBlobReference(blobName);
targetBlob.StartCopy(new Uri(sourceBlobUrl));
//Check the status;
targetBlob.FetchAttributes();
do
{
var copyState = targetBlob.CopyState;
if (copyState.Status == CopyStatus.Pending)
{
Thread.Sleep(1000);//Copy not completed. Wait for it to complete.
targetBlob.FetchAttributes();
}
else
{
break;
}
}
while (true);
Console.WriteLine("Blob with snapshot copy completed!");
}