Copying VHDs from one Azure subscription to another

The comes a time when you need to move VHDs between Azure subscriptions. You have the option of downloading the VHD locally, but at around 120GB in size, it could take a while.

There are also tools you can purchase such as Cerebrata’s Azure Management Studio for direct subscription to subscription copy, but at around $195USD for a single license, some might find it a little pricey.

This script provides an alternative method for performing a direct subscription to subscription copy using only PowerShell.

The code

First off the code!

param(
    ### URL of VHD ###
	[Parameter(Mandatory: $false)]
    [String]$srcUri,

	### Source Storage Account ###
	[Parameter(Mandatory: $false)]
    [String]$srcStorageAccount,

	### Source Storage Key ###
	[Parameter(Mandatory = $false)]
    [String]$srcStorageKey,

    # Destination Storage Account  
    [Parameter(Mandatory = $false)]
    [String]$destStorageAccount,

	### Destination container
	[Parameter(Mandatory = $false)]
    [String]$destContainer,

    # Destination Storage Key  
    [Parameter(Mandatory = $false)]
    [String]$destStorageKey"
	)

# If Azure module isn't available -> exit
if ((Get-Module -ListAvailable Azure) -eq $null)
{
    throw "Windows Azure Powershell not found! Please install from http://www.windowsazure.com/en-us/downloads/#cmd-line-tools"
}

$filename = ([System.uri]$srcUri).Segments[-1]

### Create the source storage account context ###
$srcContext = New-AzureStorageContext  `
    -StorageAccountName $srcStorageAccount `
    -StorageAccountKey $srcStorageKey

### Create the destination storage account context ###
$destContext = New-AzureStorageContext `
    -StorageAccountName $destStorageAccount `
    -StorageAccountKey $destStorageKey

### Start the asynchronous copy - specify the source authentication with -SrcContext ###
$blob = Start-AzureStorageBlobCopy  `
    -srcUri $srcUri `
    -SrcContext $srcContext `
    -DestContainer $destContainer `
    -DestBlob $filename `
    -DestContext $destContext

$blob | Get-AzureStorageBlobCopyState  -WaitForComplete

Install Azure PowerShell module.

Installing Azure PowerShell is done using the Web Platform Installer.

A number of prereqs are automatically installed including IIS8 express, WMF3.0 which includes PowerShell 3.0, MS SQL LocalDB edition, MS Azure Storage Emulator, MS Azure emulator.

Download and run the wpilauncher using the link above. Click Add on the Microsoft Azure PowerShell line, then click install.

alt text

On the Prerequisites screen, review the license terms and click I Accept to continue.

WPI EULA

Once complete, click Finish and then exit

Get rights to source and destination Azure subscription

Run Add-AzureAccount for each of the subscriptions:

PS C:\>  Add-AzureAccount
VERBOSE: Account "mattwoolnough@hotmail.com" has been added.
VERBOSE: Subscription "Visual Studio Premium with MSDN" is selected as the default subscription.
VERBOSE: To view all the subscriptions, please use Get-AzureSubscription.
VERBOSE: To switch to a different subscription, please use Select-AzureSubscription.

Id                             Type       Subscriptions                          Tenants
--                             ----       -------------                          -------
mattwoolnough@hotmail.com      User       4aff9fb2-c75b-4f6a-9b38-5cc85f197bf1   2776b29d-44e6-4be3-80ea-b3502ee11429
                                          eaeea496-6477-40f2-9a70-99c4c9fa6682   b2be9eec-85ba-4ce9-8e2b-80fe51148463


PS C:\>  Add-AzureAccount
VERBOSE: Account "matthew.woolnough@unifysolutions.net" has been added.
VERBOSE: Subscription "Visual Studio Premium with MSDN" is selected as the default subscription.
VERBOSE: To view all the subscriptions, please use Get-AzureSubscription.
VERBOSE: To switch to a different subscription, please use Select-AzureSubscription.

Id                             Type       Subscriptions                          Tenants
--                             ----       -------------                          -------
matthew.woolnough@unifysolutio User       2d8a596d-cb61-48f5-9ff4-84328c959d98   b74f1589-1bb7-4294-2461-86a27a55d8d0
ns.net                                    7ffbcee9-b148-45f3-a2f7-ee91be3220b2
                                          e7e1a9ad-96c4-40cd-b3b2-ece03551e20e

At this point it the PowerShell session has rights in both subscriptions.

Get Access Keys

Login into the Source Subscription using the New Azure Portal https://portal.azure.com/ Click either Storage Accounts (classic) or Storage Accounts - Whichever you’re using.

Select the Storage Account that contains the Disks to copy, then click the key icon to access the Manage keys screen

Use the Storage Account name and Primary Access Key in the script as srcStorageAccount and srcStorageKey

Login into the Destination subscription using the New Azure Portal https://portal.azure.com/ using a different browser. Perform the same process for the Destination Side, storing the values as destStorageAccount and destStorageKey. You will also need the container in the Storage account into which you wish the files to be copied.

Get VHD location

Select Virtual Machines (classic) from menu

Click the machine whose disk you are to copy. If it’s not switched off, do that now, then click Disks

Select the disk you wish to copy, then copy the VHD location. Use this value as srcUri in script.

This should now be enough information to run the script.

Execution

Pass in parameters gathered in previous steps as arguments as shown below.

script.ps1
 -srcUri "https://portalvhds52qvvdzm625er.blob.core.windows.net/vhds/VicUniADSERVER-VicUniADSERVER-2015-05-26.vhd" `
 -srcStorageAccount "portalvhds52qvvdzm625er" ` 
 -srcStorageKey "S6Ta1Hm<snip>TZGsqY7sYEV7A==" `
 -destStorageAccount "storage" `
 -destContainer "vhds" `
 -destStorageKey  "v<snip>iG7uz4Ql2J+9yHzdUvg==" 

If everything goes well, you should get a progress indicator at the top of the screen as shown below. You can CTRL-C to exit without impacting the copy.

Once this process has completed, you’ll see a success message like that below. You can then create a disk from a VHD & create a VM from the disk.