Wednesday, 8 February 2017

Copying an Azure Blob snapshot to another storage account using PowerShell

I've been working with Azure Blobs and Snapshots recently. One gripe is that the Azure portal and the various storage explorers don't give you the power to copy a blob snapshot. Blobs, yes, but their snapshots, no.

Depending on your requirements there are many approaches. The PowerShell below gives an example where the snapshot timestamp is extracted from the snapshot URI and then used to obtain an object to the specific snapshot before copying it with the Start-AzureStorageBlobCopy cmdlet.

# Define the source snapshot blob URI
$SrcBlobURI="https://<SOURCE_STORAGE_ACCOUNT>.blob.core.windows.net/vhds/<SOURCE_VHD_PREFIX>.vhd?snapshot=2017-01-24T21:08:36.9371576Z"

# Define the destination storage account and context.
$DestStorageAccountName = "<DESTINATION_STORAGE_ACCOUNT>"
$DestStorageAccountKey = "<DESTINATION_STORAGE_ACCOUNT_KEY>"
$DestContainerName = "<DESTINATION_CONTAINER_NAME>"
$DestContext = New-AzureStorageContext -StorageAccountName $DestStorageAccountName -StorageAccountKey $DestStorageAccountKey

# Determine source snapshot blob container name and context
$SrcDiskInfo = "" | Select StorageAccountName, VHDName, ContainerName
$SrcDiskInfo.StorageAccountName = ($SrcBlobURI -split "https://")[1].Split(".")[0]
$SrcDiskInfo.VHDName = $SrcBlobURI.Split("/")[-1]
$SrcDiskInfo.ContainerName = $SrcBlobURI.Split("/")[3]
$SrcContainerName = $SrcDiskInfo.ContainerName
$SrcStorageAccount = Find-AzureRmResource `
    -ResourceNameContains $SrcDiskInfo.StorageAccountName `
    -WarningAction Ignore
$SrcStorageKey = Get-AzureRmStorageAccountKey `
    -Name $SrcStorageAccount.Name `
    -ResourceGroupName $SrcStorageAccount.ResourceGroupName
$SrcContext = New-AzureStorageContext `
    -StorageAccountName $SrcStorageAccount.Name `
    -StorageAccountKey $SrcStorageKey[0].Value

# Extract timestamp from the Snapshot filename and convert to a datetime
$pre, $post = $SrcBlobURI.split("=")
$snapdt = [uri]::UnescapeDataString($post)
$snapdt = [datetime]::ParseExact( `
    $snapdt,'yyyy-MM-dd"T"HH:mm:ss"."fffffff"Z"',$null `
)

# Get a reference to blobs in the source container.
$blob = Get-AzureStorageBlob -Container $SrcContainerName `
    -Context $SrcContext `
    | Where-Object {`
        $_.ICloudBlob.IsSnapshot `
        -and $_.SnapshotTime -eq $snapdt `
    }

# Copy blobs from one container to another.
$blob | Start-AzureStorageBlobCopy `
    -DestContainer $DestContainerName `
    -DestContext $DestContext `
    -DestBlob "acopy_$($blob.Name)"

No comments:

Post a Comment