How to Quickly Clone a VM in Azure !

clone_VMs

Creating a clone/copy of an existing VM should ideally be done by creating an Image out of the VM and then using it to create a new VM. This is currently not the way we can do it in Azure because once you generalize the existing VM for capturing Image, the VM gets deallocated and you cannot login to it again. If you don’t generalize it and still go ahead with capturing the Image, still it will mark the VM as generalized (it basically assumes the administrator has run the steps at the OS level) and deallocates it.

So in this article we are going to see how we can clone a VM by creating Snapshot of the managed disk and then creating a new VM with it using Powershell.

Steps

  • Login to your Azure Portal and go to the VM you wish to clone.
  • Select the attached disk(s) and open it. Use the ‘Create snapshot’ option in the portal to create a snapshot of the disk. This way we get a copy of the managed disk in our Resource Group. Do this for OS as well any Data Disks which you have with the VM.

CaptureSnapshot

  • Now, click on Cloud Shell icon on the upper right corner of your Azure Portal  and select Powershell from the dropdown. Let CloudShell load the Powershell module till you see the command prompt ready.

CloudShell

  • Execute the below Powershell commands to create Managed Disk from the snapshot we captured earlier. Repeat these steps in case you have multiple disk snapshots.
#Enter name of the ResourceGroup in which you have the snapshots
$resourceGroupName ='<Resource Group Name>'

#Enter name of the snapshot that will be used to create Managed Disks
$snapshotName = '<Snapshot Name>'

#Enter name of the Managed Disk
$diskName = '<Name of the Disk to be created>'

#Enter size of the disk in GB
$diskSize = '128'

#Enter the storage type for Disk. PremiumLRS / StandardLRS.
$storageType = 'Premium_LRS'

#Enter the Azure region where Managed Disk will be created. It should be same as Snapshot location
$location = 'westus'

#Set the context to the subscription Id where Managed Disk will be created
Select-AzureRmSubscription -SubscriptionId '<Subscription ID>'

#Get the Snapshot ID by using the details provided
$snapshot = Get-AzureRmSnapshot -ResourceGroupName $resourceGroupName -SnapshotName $snapshotName 

#Create a new Managed Disk from the Snapshot provided 
$diskConfig = New-AzureRmDiskConfig -AccountType $storageType -Location $location -CreateOption Copy -SourceResourceId $snapshot.Id

$disk = New-AzureRmDisk -Disk $diskConfig -ResourceGroupName $resourceGroupName -DiskName $diskName
  • Now that we have our managed disks ready, we can go ahead and create a new VM and attach the disks to it.
#Enter the name of an existing virtual network where virtual machine will be created
$virtualNetworkName = '<VN Name>'

#Enter the name of the virtual machine to be created
$virtualMachineName = '<VM Name>'

#Provide the size of the virtual machine
$virtualMachineSize = 'Standard_DS4_v2_Promo'

#Initialize virtual machine configuration
$VirtualMachine = New-AzureRmVMConfig -VMName $virtualMachineName -VMSize $virtualMachineSize

#(Optional Step) Add data disk to the configuration. Enter DataDisk Id
$VirtualMachine = Add-AzureRmVMDataDisk -VM $VirtualMachine -Name $dataDiskName -ManagedDiskId <DataDisk ResourceID> -Lun "0" -CreateOption "Attach"

#Use the Managed Disk Resource Id to attach it to the virtual machine. Use OS type based on the OS present in the disk - Windows / Linux
$VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -ManagedDiskId $disk.Id -CreateOption Attach -Windows

#Create a public IP 
$publicIp = New-AzureRmPublicIpAddress -Name ($VirtualMachineName.ToLower()+'_ip') -ResourceGroupName $resourceGroupName -Location $snapshot.Location -AllocationMethod Dynamic

#Get VNET Information
$vnet = Get-AzureRmVirtualNetwork -Name $virtualNetworkName -ResourceGroupName $resourceGroupName

# Create NIC for the VM
$nic = New-AzureRmNetworkInterface -Name ($VirtualMachineName.ToLower()+'_nic') -ResourceGroupName $resourceGroupName -Location $snapshot.Location -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $publicIp.Id

$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $nic.Id

#Create the virtual machine with Managed Disk
New-AzureRmVM -VM $VirtualMachine -ResourceGroupName $resourceGroupName -Location $snapshot.Location

New VM will get allocated in the ResourceGroup and VNet provided. Use the same credentials (as original VM) to login to the new VM.

Comment below in case of any issues / queries.

Thanks for checking out !

Categories
Comments
All comments.
Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. Srinivas M

    Thanks for sharing the steps. This is such a basic requirement and should be available directly on portal. Azure should pick up fast.

  2. IvanD

    I don’t think this is going to work for the OS disk. Maybe they’ve changed something and now it doesn’t require you to delete the VM? It would be very nice if they did.

    1. Abhimanyu

      It works fine for OS Disk as well as has been tested last week. Let us know in case you have confirmed some change in the process.

  3. rdai111

    amazing, thank you! This works! The only thing worth pointing out is in the article you broke the script into two parts but there are variables in the first script that is used in the second.

    I ran the first script, then some how my powershell timed out or something so powershell “forgot” the variables in the first

    So I had to glue the two pieces together, comment out

    $disk = New-AzureRmDiskConfig -AccountType $storageType -Location $location -CreateOption Copy -SourceResourceId $snapshot.Id

    New-AzureRmDisk -Disk $disk -ResourceGroupName $resourceGroupName -DiskName $diskName

    and

    #(Optional Step) Add data disk to the configuration. Enter DataDisk Id
    $VirtualMachine = Add-AzureRmVMDataDisk -VM $VirtualMachine -Name $dataDiskName -ManagedDiskId -Lun “0” -CreateOption “Attach”

    since I don’t have an optional data disk, after that I ran the whole script again and it worked.

  4. Abhimanyu

    Agreed. Would have been better if I had combined the two sections of the scripts but wanted to breakdown the scripts so that they are easy to understand. Glad that it worked well for you.
    Thanks!

  5. Michael

    This has been a tremendous help and over a year latter, it’s still the only resource I could find to help me achieve this style of cloning.

  6. Dave Williams

    The instructions here will work but just be aware of one important thing:

    If you bring a new machine online that was cloned from an old machine’s OS disk, they both now have the same hostname. The new machine will remove the old machine from the directory running in Azure. This means that if you have any machines that connect to each other (e.g., a web server talking to a DB server) via its hostname, it is now broken. I know this as I have done it. This is why the generalizing step is needed.

    D.

  7. Abhimanyu

    Thanks for the comment Dave. Yes this is true but there is a workaround for it.
    You can first create a clone VM with the steps mentioned in this article and then you can generalize the cloned VM and create a new VM from the image. That way you get a generalized clone VM. 🙂

  8. joshan

    Confused by the work around. You are still creating the cloned VM before you can generalize it. How does that stop the AD changes?

  9. Jaime

    hi, when running this setp: #Create a new Managed Disk from the Snapshot provided
    $disk = New-AzureRmDiskConfig -AccountType $storageType -Location $location -CreateOption Copy -SourceResourceId $snapshot.Id

    I get the following error:
    Cannot convert ‘System.Object[]’ to the type ‘System.String’ required by parameter ‘SourceResourceId’. Specified method is not supported.

    What has changed?

    Thanks in advance

  10. Abhimanyu

    Hi @Jaime, this is a general powershell related error and not azure specific. Can you please recheck the commands you have executed and make sure there are no invalid characters.
    These commands should work fine.

    Thanks

  11. Lada Korine

    Have a question. By cloning the exiting machine, we are ending up with 2 machines now. Can those 2 machines run in the same time?

  12. Abhimanyu

    Yes they can because they will have different internal IP. Do you see any challenge with that?

  13. Stephen Henry

    I notice you reference $dataDiskName in your script yet you haven’t defined it yet.

  14. sreeja

    hi,can’t able to rdp to the new vm which got created by using the script.My requirement is only need to use private ip…no public ip should be there…and using vpn need to rdp the vm…original vm is connecting but the clonned vm is unable to rdp.

    1. Abhimanyu

      Hi Sreeja, if you want to skip assigning public Ip to the cloned VM, exclude the steps to create publicIP and mapping public ip to network interface.

      Exclude the below step
      $publicIp = New-AzureRmPublicIpAddress -Name ($VirtualMachineName.ToLower()+’_ip’) -ResourceGroupName $resourceGroupName -Location $snapshot.Location -AllocationMethod Dynamic

      Do not map public ip to nic by excluding the public ip parameter in the below script-
      $nic = New-AzureRmNetworkInterface -Name ($VirtualMachineName.ToLower()+’_nic’) -ResourceGroupName $resourceGroupName -Location $snapshot.Location -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $publicIp.Id

      RDP to new VM should work fine with the same creds of old VM. Was your VM started without any issues?

      Thanks

  15. steve88

    There is an error in the first script. The last line should read:

    $disk = New-AzureRmDisk -Disk $disk -ResourceGroupName $resourceGroupName -DiskName $diskName

    rather than
    New-AzureRmDisk -Disk $disk -ResourceGroupName $resourceGroupName -DiskName $diskName

    Also, the scripts have to be run in one session as someone noted above

    1. Abhimanyu

      Thanks for pointing out. I have updated the post with correction.
      Yes these have to be run in same session obviously.

  16. Surendra Aderu

    If the VMs are domain joined and after power ON new copied VM, is there any SID issues will occur ?
    Please confirm.

  17. Jaap Tempelman

    Currently you can create a managed disk and create a virtual machine directly from the Azure GUI without using Powershell

  18. Rob Fisher

    this is great but you don’t you use $diskSize in $diskConfig (or anywhere)

  19. Timoteo Brito

    Awesome!!! Works just fine and is really helpfull!!!

    Thank you!!!

  20. Dude

    And this is “quickly”?

    1. Abhimanyu

      This was quick when azure didn’t have clone option in azure portal. Things have changed since then 🙂

  21. Matt F

    Good work