Last active
June 20, 2019 13:02
-
-
Save mmckechney/f32f958826eb9f26f88398a9ac9c6e0c to your computer and use it in GitHub Desktop.
Copy a managed disk to another region
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Managed disks in Azure have no direct facilitites to access the underlying URL/path the disk resides in since | |
they are placed into storage accounts under the hood by Azure. Often times there's a desire to take a disk from a single | |
VM and move to another region where you can create a new VM and attach to the disk that's copied. This script | |
provides a means to do that and has been tested as working using the new AZ PowerShell cmdlets. | |
If this is run in a PowerShell context without the new AZ cmdlets installed; simply do a search and replace of Az to AzureRM. | |
Note: The SOURCE VM needs to be powered off to create the SAS URL and to ensure no writes are occuring to the disk during the copy. | |
.DESCRIPTION | |
This script will require you to populate the source resource group and source managed disk name as well as the destination resource group, | |
destination managed disk name and destination Azure region. It will create a temporary resource group and storage account for the | |
copy process, then clean up both the resource group and storage account. | |
This script takes advantage of the Grant-AzDiskAccess provding a temporary SAS token to a managed disk. | |
#> | |
#login-azaccount -- ensure you are logged in and that the context is set to the proper subscription | |
$subscriptionId = "" | |
#Location and name for the source Managed Disk | |
$sourceResourceGroupName = "" | |
$sourceDiskName = "" | |
$osType = "" # Windows or Linux | |
#Destination resource group and name for the managed disk | |
$destinationResourceGroup = "" | |
$destinationDiskName = "" | |
$destinationRegion = "" | |
#Set the subscription context | |
Set-AzContext -SubscriptionId $subscriptionId | |
#Create the temporary storage account to stage the VHD copy and get context object | |
$tempStorageAccountName = "managedcopy" + -join ((97..122) | Get-Random -Count 10 | % {[char]$_}) | |
$tempStorageAccountResourceGroup = $tempStorageAccountName + "-rg" | |
$tempVhdBlob = $tempStorageAccountName + ".vhd" | |
New-AzResourceGroup -Name $tempStorageAccountResourceGroup -Location $destinationRegion | |
New-AzStorageAccount -Name $tempStorageAccountName -ResourceGroupName $tempStorageAccountResourceGroup -SkuName Premium_LRS -Location $destinationRegion | |
$tempStorageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $tempStorageAccountResourceGroup -Name $tempStorageAccountName ).Value[0] | |
$stagingContext = New-AzStorageContext -StorageAccountName $tempStorageAccountName -StorageAccountKey $tempStorageAccountKey | |
New-AzStorageContainer -Context $stagingContext -name 'vhds' -ErrorAction SilentlyContinue | |
#Get a reference to the source managed disk and access the underlying VHD | |
$managedDisk= Get-AzDisk -ResourceGroupName $sourceResourceGroupName -DiskName $sourceDiskName | |
$sas = Grant-AzDiskAccess -ResourceGroupName $sourceResourceGroupName -DiskName $managedDisk.Name -DurationInSecond 14400 -Access Read | |
#Start copying the VHD for the source managed disk | |
$copyfile = Start-AzStorageBlobCopy -AbsoluteUri $sas.AccessSAS -DestContainer 'vhds' -DestContext $stagingContext -DestBlob $tempVhdBlob -ConcurrentTaskCount 500 | |
$blobVhdUri = $stagingContext.Context.BlobEndPoint + "vhds/" + $tempVhdBlob | |
#Get status of the copy | |
Get-AzStorageBlob -Context $stagingContext -Container 'vhds' | ForEach-Object { Get-AzStorageBlobCopyState -Blob $_.Name -Context $stagingContext -Container 'vhds' -WaitForComplete } | |
$status = $copyfile | Get-AzStorageFileCopyState | |
while ($status.Status -eq "Pending") | |
{ | |
$status = $copyfile | Get-AzStorageFileCopyState | |
Start-Sleep -Milliseconds 500 | |
} | |
#Create the new Managed Disk from the URL | |
$storageAccountId = '/subscriptions/' +$subscriptionId + '/resourceGroups/' + $destinationResourceGroup + '/providers/Microsoft.Storage/storageAccounts/' + $tempStorageAccountName | |
$diskConfig = New-AzDiskConfig -AccountType Premium_LRS -Location $destinationRegion -CreateOption Import -StorageAccountId $storageAccountId -SourceUri $blobVhdUri -OsType $osType | |
New-AzDisk -Disk $diskConfig -ResourceGroupName $destinationResourceGroup -DiskName $destinationDiskName | |
#Cleanup ---- | |
#remove the VHD access token frou the source managed disk | |
Revoke-AzDiskAccess -ResourceGroupName $sourceResourceGroupName -DiskName $sourceDiskName | |
#Delete the temporary storage account | |
Remove-AzStorageAccount -ResourceGroupName $tempStorageAccountResourceGroup -Name $tempStorageAccountName -Force | |
#Delete the temp resource group | |
Remove-AzResourceGroup -Name $tempStorageAccountResourceGroup -Force |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Modified version of script originally written by Ryan Berry that fully manages the storage account used to stage the VHD copy.
(https://github.com/microsoft/csa-misc-utils/blob/master/psh-ManagedDiskUtils/ManagedDiskCopy.ps1)