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:
- Azure can not move a managed disk
- 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://www.thomas-zuehlke.de/2019/08/creating-azure-vm-based-on-local-vhd-files/
2019-09-27 um 16:29 Uhr
Hi Thomas,
How many time take move a Snapshot to Blob Storage? I tried to move different snapshot, but, when finished the process the weight of files is 0 MB.
2019-09-27 um 19:53 Uhr
Hmm, if you upload via internet, it depends on you connection. If you move from one storage account to another, you use the Azure backbone and it is realy fast. The transfer should start immediatly, therefore size of 0 seems to be a wrong.
If you upload from local keep in mind to use PageBlob and a fixed size of the VHD files like described here: http://thomas-zuehlke.de/2019/08/creating-azure-vm-based-on-local-vhd-files/
2019-08-29 um 5:27 Uhr
Thanks for such a good starting point. I have modified your script to copy a VM snapshot (VHD) from one tenant to another. I have also upgraded your scripts to use the new Az libraries and combined them into one. See below…
# ========================================================================================
# Copy a snapshot (.VHD file) to another tenant and subscription.
# First half takes place on the source tenant.
# Copy the VM snapshot (*.VHD file) from the resource group into a storage account, first.
# ========================================================================================
$sourceTenantId = “”
$sourceSubscriptionId = “”
$sourceStorageAccountName = “”
$sourceStorageAccountKey = “”
$sourceStorageAccountContainer = “foldername”
Connect-AzAccount -Tenant $sourceTenantId -SubscriptionId $sourceSubscriptionId
# The path of the download URL of the snapshot. Need to click the download link to autogenerate the SAS.
$VHDDownloadUri = “https://x.blob.core.windows.net/x/x?sv=x”
$targetSnapshotName = “snapshot.vhd”
# Download snapshot to StorageAccount-Source (the storage account is located in the source subscription)
Set-AzContext -SubscriptionId $sourceSubscriptionId
$sourceStorageAccountContext = New-AzStorageContext –StorageAccountName $sourceStorageAccountName -StorageAccountKey $sourceStorageAccountKey
Start-AzStorageBlobCopy -AbsoluteUri $VHDDownloadUri -DestContainer $sourceStorageAccountContainer -DestContext $sourceStorageAccountContext -DestBlob $targetSnapshotName
# ========================================================================================
# Second half takes place on the destination tenant.
# Now copy the VM snapshot (*.VHD file) over to a storage account in a different tenant.
# ========================================================================================
$destTenantId = “”
$destSubscriptionId = “”
$destStorageAccount = “”
$destStorageAccountKey = “”
$destStorageAccountContainer = “foldername”
Connect-AzAccount -Tenant $destTenantId -SubscriptionId $destSubscriptionId # Enter in destination credentials.
Set-AzContext -SubscriptionId $destSubscriptionId
$destStorageAccountContext = New-AzStorageContext –StorageAccountName $destStorageAccount -StorageAccountKey $destStorageAccountKey
# Start the copy…
$blobCopy = Start-AzStorageBlobCopy -DestContainer $destStorageAccountContainer -DestContext $destStorageAccountContext -SrcBlob $targetSnapshotName -Context $sourceStorageAccountContext -SrcContainer $sourceStorageAccountContainer
Write-Host ($blobCopy | Get-AzStorageBlobCopyState).CopyId
Write-Host ($blobCopy | Get-AzStorageBlobCopyState).TotalBytes
Write-Host ($blobCopy | Get-AzStorageBlobCopyState).BytesCopied
while(($blobCopy | Get-AzStorageBlobCopyState).Status -eq “Pending”)
{
Start-Sleep -s 5
#$blobCopy | Get-AzStorageBlobCopyState
$output = “`r” + ($blobCopy | Get-AzStorageBlobCopyState).BytesCopied
Write-Host $output -NoNewline
}
# End of script.
2019-03-18 um 17:59 Uhr
Tenant != Subscription
This moves items between subscriptions within the same AAD tenant not between two different tenants. e.g. corp1.onmicrosoft.com to corp2.onmicrosoft.com
2019-04-18 um 11:47 Uhr
Yes, Tenants != Subscriptions.
In general, these steps should also work across tenants. Maybe there are problems with Start-AzureStorageBlobCopy, but you can also move the VHD with:
azcopy cp “https://[srcaccount].blob.core.windows.net/[container]/[path/to/blob]?[SAS]” “https://[destaccount].blob.core.windows.net/[container]/[path/to/blob]?[SAS]”
or other ways.
2018-10-04 um 17:45 Uhr
hello! thanks for your post it worked fine. please is it possible to move an entire resource group from azure subscription CSP to another Tenant subscription?
2018-10-08 um 17:05 Uhr
Hi Kennedy,
no, it is not possible to move the entire RG to another tenant in the Azure Portal. If you move the RG, you can only move the resources inside the group to an existing or new RG in a target subscription.