Is it possible to migrate Azure VM image from one Subscription to another Subscription?
Solution 1
Try this:
Select-AzureSubscription -SubscriptionName "EXISTING SUBSCRIPTION NAME"
#Get-AzureVM
$vmName = "YOUR_VM_NAME"
$serviceName = "CLOUD_SERVICE_NAME"
$destServiceName = "NEW_CLOUD_SERVICE_NAME"
$workingDir = (Get-Location).Path
$sourceVm = Get-AzureVM -ServiceName $serviceName -Name $vmName
$vmConfigurationPath = $workingDir + "\exportedVM.xml"
$sourceVm | Export-AzureVM -Path $vmConfigurationPath
$sourceOSDisk = $sourceVm.VM.OSVirtualHardDisk
$sourceDataDisks = $sourceVm.VM.DataVirtualHardDisks
$sourceStorageName = $sourceOSDisk.MediaLink.Host -split "\." | select -First 1
$sourceStorageAccount = Get-AzureStorageAccount -StorageAccountName $sourceStorageName
$sourceStorageKey = (Get-AzureStorageKey -StorageAccountName $sourceStorageName).Primary
Stop-AzureVM -ServiceName $serviceName -Name $vmName -Force
Select-AzureSubscription -SubscriptionName "NEW SUBSCRIPTION NAME"
$location = $sourceStorageAccount.Location
$destStorageAccount = Get-AzureStorageAccount | ? {$_.Location -eq $location} | select -first 1
if ($destStorageAccount -eq $null)
{
$destStorageName = "NEW_STORAGE_NAME"
New-AzureStorageAccount -StorageAccountName $destStorageName -Location $location
$ destStorageAccount = Get-AzureStorageAccount -StorageAccountName $destStorageName
}
$destStorageName = $destStorageAccount.StorageAccountName
$destStorageKey = (Get-AzureStorageKey -StorageAccountName $destStorageName).Primary
$sourceContext = New-AzureStorageContext -StorageAccountName $sourceStorageName `
-StorageAccountKey $sourceStorageKey
$destContext = New-AzureStorageContext -StorageAccountName $destStorageName `
-StorageAccountKey $destStorageKey
if ((Get-AzureStorageContainer -Context $destContext -Name vhds -ErrorAction SilentlyContinue) -eq $null)
{
New-AzureStorageContainer -Context $destContext -Name vhds
}
$allDisks = @($sourceOSDisk) + $sourceDataDisks
$destDataDisks = @()
foreach($disk in $allDisks)
{
$blobName = $disk.MediaLink.Segments[2]
$targetBlob = Start-CopyAzureStorageBlob -SrcContainer vhds -SrcBlob $blobName `
-DestContainer vhds -DestBlob $blobName `
-Context $sourceContext -DestContext $destContext -Force
Write-Host "Copying blob $blobName"
$copyState = $targetBlob | Get-AzureStorageBlobCopyState
while ($copyState.Status -ne "Success")
{
$percent = ($copyState.BytesCopied / $copyState.TotalBytes) * 100
Write-Host "Completed $('{0:N2}' -f $percent)%"
sleep -Seconds 5
$copyState = $targetBlob | Get-AzureStorageBlobCopyState
}
If ($disk -eq $sourceOSDisk)
{
$destOSDisk = $targetBlob
}
Else
{
$destDataDisks += $targetBlob
}
}
Add-AzureDisk -OS $sourceOSDisk.OS -DiskName $sourceOSDisk.DiskName -MediaLocation $destOSDisk.ICloudBlob.Uri
foreach($currenDataDisk in $destDataDisks)
{
$diskName = ($sourceDataDisks | ? {$_.MediaLink.Segments[2] -eq $currenDataDisk.Name}).DiskName
Add-AzureDisk -DiskName $diskName -MediaLocation $currenDataDisk.ICloudBlob.Uri
}
Get-AzureSubscription -Current | Set-AzureSubscription -CurrentStorageAccountName $destStorageName
$vmConfig = Import-AzureVM -Path $vmConfigurationPath
New-AzureVM -ServiceName $destServiceName -Location $location -VMs $vmConfig -WaitForBoot
Get-AzureRemoteDesktopFile -ServiceName $destServiceName -Name $vmConfig.RoleName -LocalPath ($workingDir+"\newVM.rdp")`
Solution 2
Azure provides little support for switching any Azure service from one Subscription to another.
If you create a ticket, I have done this by the way, you can have Azure support staff manually switch ALL services from one Subscription (source) to another Subscription (destination) where the destination Subscription has NO services in that Subscription.
You CANNOT select individual services from the source Subscription to transfer, to the destination Subscription (its all or nothing from the source Subscription) and you CANNOT have any existing services in the destination Subscription.
**A service is any Azure feature (VM, Website, Storage Blob etc)
It is likely that the support rep has not done this procedure before and you will have to let them know it is possible, my support rep for the ticket took about a week to figure it all out. Make sure you use the vernacular source Subscription and destination Subscription with GUIDs for both Subscriptions in all conversations with the Azure support rep.
Now for a VM in particular, it looks like you can copy a VM from one storage account to another using a tool called AzCopy, check out this article:
http://thecodejunkie.com/2014/01/20/copying-virtual-machines-between-azure-subscriptions/
Related videos on Youtube
billcyz
Updated on September 18, 2022Comments
-
billcyz over 1 year
I recently captured one azure vm image in one storage account, and planning to migrate this image to another storage account under a different subscription. I used PowerShell Script to run this task, but I came across with this problem: The storage account was not found. And one more concern is that PowerShell has to be related to the specific Azure Account, otherwise it can not run script. So the story is how to use PowerShell control different subscriptions at the same time, and also perform the migration task?? Thank You.
BTW, the PowerShell script is shown below:
Change these to match the source account
$sourceStorageAccountName = "" $sourceContainerName = "" $sourceStorageKey = "" #Need this if moving data from a different subscription
Destination Account Information
$destStorageAccountName = Read-Host "Enter Destination Storage Account Name" $destStorageAccountKey = Get-AzureStorageKey $destStorageAccountName | %{$_.Primary} $destContainerName = Read-Host "Enter Destination Container Name"
$sourceContext = New-AzureStorageContext -StorageAccountName $sourceStorageAccountName -StorageAccountKey $sourceStorageKey -Protocol Http $destContext = New-AzureStorageContext -StorageAccountName $destStorageAccountName -StorageAccountKey $destStorageAccountKey
$uri = $sourceContext.BlobEndPoint + $sourceContainerName +"/"
Copy Operation
Get-AzureStorageBlob
-Context $sourceContext
-Container $sourceContainerName | ForEach-Object{ Start-AzureStorageBlobCopy
-SrcUri "$uri$($_.Name)"-DestContext $destContext
-DestContainer $destContainerName-DestBlob "hackathon/$($_.Name)"
}Checking Status of Blob Copy -- This can be commented out if no confirmation is needed
Get-AzureStorageBlob
-Context $sourceContext
-Container $sourceContainerName | ForEach-Object{ Get-AzureStorageBlobCopyState
-Blob $_.Name-Context $destContext
-Container $destContainerName-WaitForComplete
}The problem is like this: Get-AzureStorageKey : No current subscription has been designated. Use Select-AzureSubscription -Current to set the current subscription.
-
mvladk almost 9 yearsStep by step manual that worked for me blogs.msdn.com/b/microsoft_press/archive/2014/01/29/…
-
-
billcyz over 9 yearsSorry, when I run this script, it shows this problem: + If ($disk –eq $sourceOSDisk) + ~ Unexpected token ')' in expression or statement.
-
Michael Hampton over 9 years@billcyz Looks like some of the hyphens were replaced with (not very) "smart" ones. I made a pass through them and took them out.
-
raja over 9 years@MichaelHampton thanks, I suspect the paste process replaced them. I pasted then made it a code block, I should have put in the code block then pasted.
-
andreimarinescu almost 9 yearsI used AzCopy to copy over the entire VHDS blob container over and the recreated the disks for the VMs in the new subscription. Worked like a charm, copied 300GB+ in 1h51min
-
Royden Rego about 7 yearsAny way this script can be made to work with multiple VM's under a cloud service?