How can I migrate my Azure VMs to Azure Resource Management (ARM) stack?

That's a perfectly good question and one that many teams are facing lately. There is a valid reason to want to upgrade. The Azure Resource Manager (ARM) has a lot of advantages over it's predecessor. The biggest one is automation. ARM templates allow you to easily capture, configure and deploy resources and resource groups on Azure using PoSH (PowerShell) and simple Json files. This is great for DevOps! If you're starting with Azure now, then ARM makes absolute sense and is the default option. However, there are many companies that are stuck in v1 i.e the Azure Service Management (ASM) stack waiting for a reliable way to upgrade.

In this post, we will take advantage of a new Open Source tool, conveniently named [ASM2ARM](" target="_blank) to migrate a single VM from the v1/ASM stack to the v2/ARM stack.


The ASM2ARM tool can generate and/or execute all the necessary scripts to migrate the VM along with its associated extensions, resource group, virtual network and subnet. The tool comes with some limitations so you should be aware of this before embarking in a mass migration exercise. The biggest one, at the moment, is that the original VM in the v1 stack needs to be stopped for the migration to take place. This could cause business disruption if you rely on that one VM for critical operations. The full list of limitations can be found here: [](" target="_blank).

Show me the code

With the limitations known to us, we can go ahead and run through a single migration to see how it works.


You need the latest version of PowerShell (v5.0 or later) and the Microsoft Azure PowerShell module. The module contains all the PowerShell cmdlets (commands) that can be used to manage our Azure infrastructure. You can get them from the official [Azure downloads page](" target="_blank).


  • Open an elevated (run as admin) PowerShell window
  • Run the following code (one line at a time)

Upon running the last command and if you're error-free, you should see the following message:

WARNING: GeoReplicationEnabled property will be deprecated in a future release of Azure
PowerShell. The value will be merged into the AccountType property.
Run the following line to deploy the generated templates and scripts

New-AzureSmToRMDeployment -ResourceGroupName '<newResourceGroup>' -Location 'East US' -ServiceName 'somename-vm1' -Name 'somename-vm1' -StorageAccountName 'visualstudioenterpriarm' -SetupTemplateFileName 'C:\temp\output\somename-vm1-somename-vm1-setup.json' -ParametersFileName 'C:\temp\output\somename-vm1-somename-vm1-parameters.json' -DeployTemplateFileName 'C:\temp\output\somename-vm1-somename-vm1-deploy.json' -CopyDisksScript 'C:\temp\output\somename-vm1-somename-vm1-copydisks.ps1' -ImperativeScript 'C:\temp\output\somename-vm1-centrica-vm1-setextensions.ps1'

Same commandline can also be found in C:\temp\output\somename-vm1-somename-vm1-deploy.ps1

This is the command that you need to run to fully migrate your VM. Alternatively, you can go into the designated output folder and check the generate somename-vm1-somename-vm1-deploy.ps1 to ensure that everything is in order. I would also urge you to check the other auto-generated files to make sure you're happy with the expected names, regions and network settings. The folder should contain the following files (names will differ based on your variable names):

  • somename-vm1-somename-vm1-copydisks.ps1
  • somename-vm1-somename-vm1-deploy.json
  • somename-vm1-somename-vm1-deploy.ps1
  • somename-vm1-somename-vm1-parameters.json
  • somename-vm1-somename-vm1-setextensions.ps1
  • somename-vm1-somename-vm1-setup.json

Once you're happy you can go ahead and execute the script using one of the two ways above. Note that the migration takes a bit of time (5-7mins), especially when copying the vhd files.

In the end, you should have a new v2 server deployed and the migration output should look like this:

Job done!


I would love to see the following features added to the tool:

  • Ability to do it on a per resource group. I would love to be able to grab the whole resource group with as many VMs it encompasses and migrated to v2
  • Ability to define vNet and SubNet names

However, these feature requests may be totally redundant as the team is hard at work integrating the migration process in the Azure Portal. The goal is to make the migration as seamless as possible by not having, for example, to stop the VMs.

I hope that you'll find this tool useful and, as always, feel free to leave a comment if you have any questions.

  • Share this post on