Copy Azure VMs Across Resource Groups

Hi Guys,

I need some help with my script;

I’m trying to clone OS disks for a groups of VMs running on a Resource Groups ($RG1) to another Resource Group ($RG2) by taking a snapshot from each OS disk and saving it on the new Resource Group, then build a new VMs on the new Resource Group and attach the cloned disks to these new VMs.

It works if I do it one by one. However when I try to do it as a bulk i get lots of errors.

# Take a snapshot of a VM Disk

$RG1= Get-AzureRmResourceGroup -Name RG1 | Select -ExpandProperty ResourceGroupName # Source RG

$RG2= New-AzureRmResourceGroup -Name RG2 -Location 'Central US'

$VMs= Get-AzureRmVM -ResourceGroupName $RG1 | Select -ExpandProperty Name

foreach ($VM in $VMs) {

$SnapConf= New-AzureRmSnapshotConfig -SourceUri $VM.StorageProfile.OsDisk.ManagedDisk.Id -Location 'Central US' -CreateOption copy

foreach ($Conf in $SnapConf) {

New-AzureRmSnapshot -ResourceGroupName $RG2 -SnapshotName $VM-Snap -Snapshot $SnapConf



When I execute the first part gives me an error “New-AzureRmSnapshot : Required parameter ‘sourceUri’ is missing (null).”


The next part, is for building disks and VMs from the Snapshots

# Build a Disk & VM from that Snapshot
# Not sure how to create the following variables
$SnapshotNames= Get-AzureRmSnapshot -ResourceGroupName $RG2 | Select -ExpandProperty Name

foreach ($SnapName in $SnapshotNames) {

$VMSize= "Standard_F4s"

$VNet= Get-AzureRmVirtualNetwork -Name $Vnet -ResourceGroupName $RG2

$OSDiskNames= $SnapName.Name # Not sure if that will work

foreach ($OSDiskname in $OSDiskNames){

$PIPs= New-AzureRmPublicIpAddress -Name $SnapName-PIP -ResourceGroupName $RG2 -Location 'Central US' -AllocationMethod Dynamic

foreach ($PIP in $PIPs) {

$NICs= New-AzureRmNetworkInterface -Name $SnapName-NIC1 -ResourceGroupName $RG2 -Location 'Central US' -SubnetId $VNet.Subnets[0].Id -PublicIpAddressId $PIP.Id

foreach ($NIC in $NICs){

$DisksConfigs= New-AzureRmDiskConfig -Location 'Central US' -SourceResourceId $SnapName.Id -CreateOption Copy

foreach ($DisksConfig in $DisksConfigs) {

$NewDisks= New-AzureRmDisk -Disk $DiskConfig -ResourceGroupName $RG2 -DiskName $OSDiskname

$NewVMS= $SnapName.Name # Not sure if that will work

foreach ($NewVM in $NewVMS) {

$VMConfigs= New-AzureRmVMConfig -VMName $NewVM -VMSize $VMSize

foreach ($VMconf in $VMConfigs) {Set-AzureRmVMOSDisk -VM $VMConfig -ManagedDiskId $NewDisk.Id -CreateOption Attach -Windows

Add-AzureRmVMNetworkInterface -VM $VMConfig -Id $NIC.Id

New-AzureRmVM -VM $VMConfig -ResourceGroupName $RG2 -Location 'US Central'








For the first part, creating the snapshots, I created a csv file that contains Snapshot name, URI-ID and was able to clone disks as bulk on the second resource group name, and it worked :slight_smile:

$List= Import-Csv -Path C:\Data\List.csv

foreach ($Name in $List)


$ID= $name.Id

$SnapName= $Name.SnapName

New-AzureRmSnapshotConfig -SourceUri $ID -Location 'US Central' -CreateOption copy | %{New-AzureRmSnapshot -ResourceGroupName $RG2 -SnapshotName $SnapName -Snapshot $_ }


Thinking of the second part to create disks from these snapshots and create new vms and attach the new provisioned disks to each vm! any thoughts ?