Moving an Azure VM from one virtual network (VNet) to another VNet is not a new problem. If you find yourself having to do this just know it is a pain. Anyone that has faced the Vnet-to-Vnet VM Move conundrum before knows that moving a VM to another subnet is a trivial task and would think a VM move to another VNet would be the same. However, when it comes to moving a VM to a new VNet there is no supported way to do this from Microsoft and that is by design. There are some workarounds to moving a VM to a new VNet but in the end these boil down to redeploying the VM. When moving a VM to a new VNet you will need to plan for downtime.
In this blog post, I am not going to go through the steps of the workarounds for moving a VM to a new VNet. There are plenty of other blog posts out there covering how to do this manually or using ASR. If you want to read up on this there is one article I keep bookmarked by Microsoft MVP Tim Warner that you can find here. In this blog post, I am going to share and talk about a PowerShell script I pulled together to make the Vnet-to-Vnet VM Migration less painful by automating it. Download link is at the end of this blog post. I put together the script to work with PowerShell 5 using the AzureRM Module and one that works with PowerShell 7 (Core) using the AZ module.
Again, in general, the script is not moving the VM. The script is facilitating a migration of sorts by creating a new VM in new VNet while retaining the original VMs configuration and data disks. Here are the steps that are performed in the script:
(1) Gathers info on existing VM, VNet, and subnet.
(2) Removes the original VM while saving all data disks and VM info.
(3) Creates VM configuration for new VM, creates nic for new VM, and new availability set.
(4) Adds data disks to new VM, adds nics to new VM, adds VM to the new VNet.
(5) Creates new VM and adds the VM to the new VNet.
Let’s look at some other general information about the script. The script is a single script that has code for both PowerShell 5 using the AzureRM Module and PowerShell 7 (Core) using the AZ module. When you run the script it prompts you to choose what Azure module you are using. The script is interactive so it will prompt you to log in and prompt you for your Azure subscription in case you are running multiple subscriptions. The script is intended to migrate a single VM. It assumes the VM is deployed into an availability set and will migrate to a new availability set or in the existing availability set. You can also migrate to a new resource group or place the new VM in the existing resource group. Ok. Let’s dive into running the script. Here is a walk-through of running the script.
Open PowerShell and run Vnet-to-Vnet VM migration.ps1.
You will first be prompted for the following information:
Enter the Resource Group of the original VM:
Enter the original VM name:
Enter the new VM name:
Enter the new availability set name:
Enter the new VNet resource group:
Enter the new VNet name:
Enter the new Subnet name:
Next, you will be prompted to select your PowerShell version and Azure module as shown in the following screenshot.
The main differences between PowerShell 5 using the AzureRM Module and PowerShell 7 (Core) using the AZ module are the interactive login methods as well as cmdlets. Here are screenshots of the different logins.
PowerShell 5 with AzureRM Module:
A window will pop up for you to log into your Azure account.
Next a grid will pop up for you to select your subscription from the list.
PowerShell 7 (Core) with AZ module:
A warning will pop up prompting you with the device login info. To log into Azure go to https://microsoft.com/devicelogin and entering the code the warning gave you as shown in the screenshot.
List of your subscriptions will output. Go ahead and copy the subscription ID you plan to use. NOTE* Ignore this if you only have one subscription.
You are prompted to enter your subscription ID. This is to set the PowerShell session to the specified Azure subscription. Again ignore this if you only have 1 subscription. Note if you leave it blank and click enter it will error. Even with the error, it will finish the rest of the script just fine.
Next in both PS 5 or PS 7 you will see the following prompt confirming that you want to remove the specified original VM. Confirm yes and press enter.
Virtual machine removal operation
This cmdlet will remove the specified virtual machine. Do you want to continue?
[Y] Yes [N] No [S] Suspend [?] Help (default is “Y”): Y
NOTE* the rest of the script will run. It will take a while so be patient. As it runs you should see some output similar to this:
OperationId : a4299a3f-ea34-4c22-ba71-f6cc42ebbdff
Status : Succeeded
StartTime : 9/9/2019 5:33:14 PM
EndTime : 9/9/2019 5:50:30 PM
Error :
||
||
WARNING: Since the VM is created using premium storage or managed disk, existing standard storage account, diagstwfyhhi3jyz54e, is used for boot diagnostics.
VERBOSE: Performing the operation “New” on target “VMMove012”.
When it is all said and done if it was successful you will see:
RequestId :
IsSuccessStatusCode : True
StatusCode : OK
ReasonPhrase : OK
That’s it. Now go into the Azure portal and you will see that your VM is moved to a new VNet and will have the data disks still. Check out the following screenshots for an example showing what the resource groups look like before and after the script runs.
Before |
|
After |
|
I have used this script and it has saved me time and avoid a headache. The goal is this will be useful for others as well. You can download the version of the script released with this blog post here: https://gallery.technet.microsoft.com/VM-VNet-to-VNet-Migration-a7308ca2
If you want to contribute and enhance the script check it out on GitHub here: https://github.com/Buchatech/Azure-VM-VNet-to-VNet-Migration-Script