1

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.

billcyz
  • 1,720
  • 3
  • 13
  • 16
  • Step by step manual that worked for me http://blogs.msdn.com/b/microsoft_press/archive/2014/01/29/from-the-mvps-copying-a-virtual-machine-from-one-windows-azure-subscription-to-another-with-powershell.aspx – mvladk Jul 08 '15 at 21:25

3 Answers3

2

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")`
Reaces
  • 5,597
  • 4
  • 38
  • 46
Jim B
  • 24,081
  • 4
  • 36
  • 60
  • Sorry, when I run this script, it shows this problem: + If ($disk –eq $sourceOSDisk) + ~ Unexpected token ')' in expression or statement. – billcyz Dec 31 '14 at 07:44
  • @billcyz Looks like some of the hyphens were replaced with (not very) "smart" ones. I made a pass through them and took them out. – Michael Hampton Dec 31 '14 at 07:54
  • @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. – Jim B Dec 31 '14 at 13:54
  • Bit late here probably, but good script, stands the test of time. However it lacks the logic to include different blobs and different container names. Had to update it quite a bit. Regardless, works! Thx! – Reaces Aug 07 '15 at 11:13
  • Any way this script can be made to work with multiple VM's under a cloud service? – Royden Rego May 24 '17 at 18:45
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/

Brian
  • 321
  • 3
  • 5
  • 15
  • 1
    I 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 – andreimarinescu Jun 15 '15 at 11:17
0

You can use DC Migration Tool, an open source tool to copy azure resources from one subscription to other subscription across data centers as well.

Azure Data Center Migration Tool Blog http://blog.persistentsys.com/index.php/2015/01/06/persistent-systems-releases-azure-data-center-migration-solution/