I need to move a managed Disk from a source subscription to a destination subscription. And I started with the “Move to another subscription” option.

But there are two problem:

  1. Azure can not move a managed disk
  2. My subscription was not in the subscription list, because it belongs to another tenant.

So I created a snapshot of the managed disk and moved it to a stoage account in the source subscription, copied the snapshot to a storage account in the destination subscription and created a managed disk out of the snapshot and a VM with the managed disk afterwards. Here are the main steps in PowerShell.

A: Download the disk snapshot to a storage account

$sourceSubscriptionId = ''
$sourceStorageAccountName = "SourceStorageAccount"
$sourceStorageAccountKey = "9O1...Kg=="
$sourceStorageAccountContainer = "containername"

# path of the download URL of the snapshot
$VHDDownloadUri = "https://....blob.core.windows.net/..."
$targetSnapshotName = "snapshot.vhd"

#download snapshot to StorageAccount-Source (the storage account is located in the source subscription)
Select-AzureRmSubscription -SubscriptionId $sourceSubscriptionId
$sourceStorageAccountContext = New-AzureStorageContext –StorageAccountName $sourceStorageAccountName -StorageAccountKey $sourceStorageAccountKey
Start-AzureStorageBlobCopy -AbsoluteUri $VHDDownloadUri -DestContainer $sourceStorageAccountContainer -DestContext $sourceStorageAccountContext -DestBlob $targetSnapshotName

B: Copy the snapshot to a storage account in the destination subscription of an other tenant:

$destSubscriptionId = ''
$destStorageAccount = "DestStorageAccount"
$destStorageAccountKey = "Pqn.../Q=="
$destStorageAccountContainer = "container"

Select-AzureRmSubscription -SubscriptionId $destSubscriptionId
$destStorageAccountContext = New-AzureStorageContext –StorageAccountName $destStorageAccount -StorageAccountKey $destStorageAccountKey
Get-AzureStorageBlobCopyState -Context $destStorageAccountContext -Blob $targetSnapshotName
$blobCopy = Start-AzureStorageBlobCopy -DestContainer $destStorageAccountContainer -DestContext $destStorageAccountContext -SrcBlob $targetSnapshotName -Context $sourceStorageAccountContext -SrcContainer $sourceStorageAccountContainer
Write-Host ($blobCopy | Get-AzureStorageBlobCopyState).CopyId
Write-Host ($blobCopy | Get-AzureStorageBlobCopyState).TotalBytes
Write-Host ($blobCopy | Get-AzureStorageBlobCopyState).BytesCopied
while(($blobCopy | Get-AzureStorageBlobCopyState).Status -eq "Pending")
{
    Start-Sleep -s 5
    #$blobCopy | Get-AzureStorageBlobCopyState
    $output = "`r" + ($blobCopy | Get-AzureStorageBlobCopyState).BytesCopied
    Write-Host $output -NoNewline
}

The copy process runs asynchronous. If you need to stop the copy process, get the CopyId and use the Stop-AzureStorageBlogCopy command: Stop-AzureStorageBlobCopy -Container $destStorageAccountContainer -Blob $targetSnapshotName -CopyId "<GUID>" -Context $destStorageAccountContext

C: Create a new VM and use the snapshot.vhd from the DestStorageAccount as base image for the managed disk:

$rgName = "DestResourceGroup"
$location = "northeurope"
$storageName = "MyVMstorage"
$storageType = "Standard_LRS"
$nicname = "MyVM-nic"
$subnet1Name = "MyVM-subnet"
$vnetName = "MyVM-vnet"
$vnetAddressPrefix = "10.0.0.0/16"
$vnetSubnetAddressPrefix = "10.0.0.0/24"
$vmName = "MyVM"
$vmSize = "Standard_D2s_v3"
$osDiskName = $vmName + "osDisk"
$osDiskUri = "https://deststorageaccount.blob.core.windows.net/container/snapshot.vhd"

$storageacc = New-AzureRmStorageAccount -ResourceGroupName $rgName -Name $storageName -Type $storageType -Location $location
$pip = New-AzureRmPublicIpAddress -Name $nicname -ResourceGroupName $rgName -Location $location -AllocationMethod Dynamic
$subnetconfig = New-AzureRmVirtualNetworkSubnetConfig -Name $subnet1Name -AddressPrefix $vnetSubnetAddressPrefix
$vnet = New-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $rgName -Location $location -AddressPrefix $vnetAddressPrefix -Subnet $subnetconfig
$nic = New-AzureRmNetworkInterface -Name $nicname -ResourceGroupName $rgName -Location $location -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id
$vm = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id

$discStorageAcc = Get-AzureRmStorageAccount -ResourceGroupName $ResourceGroup -Name $destStorageAccount
$diskConfig = New-AzureRmDiskConfig -AccountType 'PremiumLRS' -Location $location -CreateOption Import -StorageAccountId ($discStorageAcc.Id) -SourceUri $osDiskUri
$disk = New-AzureRmDisk -Disk $diskConfig -ResourceGroupName $rgName -DiskName "managedsnapshot"
$vm = Set-AzureRmVMOSDisk -VM $vm -ManagedDiskId $disk.Id -CreateOption Attach -Windows

New-AzureRmVM -ResourceGroupName $rgName -Location $location -VM $vm -Verbose

If your image is syspreped, you can use: $vm = Set-AzureRmVMOperatingSystem -VM $vm -Windows -ComputerName $computerName -Credential (Get-Credential) -ProvisionVMAgent -EnableAutoUpdate before you create the VMOSDisk.

If you want to manage the disk by yourself (unmanaged disk), you can create a VM at line 23 with $vm = Set-AzureRmVMOSDisk -VM $vm -Name $osDiskName -VhdUri $osDiskUri -CreateOption Attach -Windows.


If you have the VHD files on your local environment, you can follow this steps to upload them and create a new VM:
https://blog.zuehlke.cloud/2019/08/creating-azure-vm-based-on-local-vhd-files/