Move Azure VM across Cloud Service


 

I came across a requirement of moving my azure VMs from one cloud service to another in same subscription. I had Azure VMs having same prefix like ‘MyProjectVM(N)’ where N is from 1..N. So here comes my blog providing such solution.

Below is the code to move a VM from one cloud service to another and then we will look later as to how we can reuse this code to move multiple VMs.

Prerequisites

Virtual Network, Affinity Group and Storage Account are already created.

Steps to move one VM

1. Manual Step from Microsoft Azure Portal – Create a New Cloud Service(destination cloud service), if not already exists. Create a TestVM in the new cloud service with required affinity group and virtual network information mentioned while creating. This step is required if you want to associate your destination cloud service with the virtual network. We can delete TestVM once at least one VM is moved to the destination cloud service.

2. Follow Below steps to move VM

a. Declare Variables

   1: #Step 1 : Declare Variables
   2: $CurrentCloudServiceName = "CurrentService"
   3: $NewCloudServiceName = "NewService"
   4: $StorageAccount = "MyProjectStoarge"
   5: $SubscriptionName = "My Project Subscription"
   6: $VMNameToMove = "MyProjectVM1"
   7: $SavedVMStateFilePath = "E:\XML\MyProjectVM1.xml"

b.  Set Storage Account

   1: #Step 2 : Set Azure Subscription
   2: Set-AzureSubscription -SubscriptionName $SubscriptionName -CurrentStorageAccountName $StorageAccount
   3: Select-AzureSubscription $SubscriptionName

c. Export VM

   1: #Step 3 : Export VM
   2: Get-AzureVM -ServiceName $CurrentCloudServiceName -Name $VMNameToMove
   3: Export-AzureVM -ServiceName $CurrentCloudServiceName -Name $VMNameToMove-path $SavedVMStateFilePath

d. Edit Azure VM Saved State XML File

This step is required to avoid conflicts in PowerShell endpoint public port.

Open XML File saved in step ‘Export-AzureVM’ above. Look for PowerShell Endpoint which ‘5986’ by default. Modify ‘Port””’ number which is the public port information. Keep ‘LocalPort’ as it is. Save file and close it.

   1: <InputEndpoint>
   2:   <LocalPort>5986</LocalPort>
   3:   <Name>PowerShell</Name>
   4:   <Port>61204</Port>
   5:   <Protocol>tcp</Protocol>
   6:   <Vip>**.**.**.***</Vip>
   7:   <EnableDirectServerReturn>false</EnableDirectServerReturn>
   8: </InputEndpoint>
e. Remove Azure VM
   1: #Step 5 : Remove VM
   2: Remove-AzureVM -ServiceName $CurrentCloudServiceName -Name $VMNameToMove
f. Import Azure VM into new Cloud Service
   1: #Step 6 : Import VM to new Cloud Service
   2: Import-AzureVM -Path $SavedVMStateFilePath | New-AzureVM -ServiceName $NewCloudServiceName
g. Delete TestVM manually from Microsoft Azure Portal.
The full script will look like below:-
   1: #Step 1 : Declare Variables
   2: $CurrentCloudServiceName = "CurrentService"
   3: $NewCloudServiceName = "NewService"
   4: $StorageAccount = "MyProjectStoarge"
   5: $SubscriptionName = "My Project Subscription"
   6: $VMNameToMove = "MyProjectVM1"
   7: $SavedVMStateFilePath = "E:\XML\MyProjectVM1.xml"
   8:
   9: #Step 2 : Set Azure Subscription
  10: Set-AzureSubscription -SubscriptionName $SubscriptionName -CurrentStorageAccountName $StorageAccount
  11: Select-AzureSubscription $SubscriptionName
  12:
  13: #Step 3 : Export VM
  14: Get-AzureVM -ServiceName $CurrentCloudServiceName -Name $VMNameToMove
  15: Export-AzureVM -ServiceName $CurrentCloudServiceName -Name $VMNameToMove -path $SavedVMStateFilePath
  16:
  17: #Step 4 : Edit Saved State (Manual Step)
  18:
  19: #Step 5 : Remove VM
  20: Remove-AzureVM -ServiceName $CurrentCloudServiceName -Name $VMNameToMove
  21:
  22: #Step 6 : Import VM to new Cloud Service
  23: Import-AzureVM -Path $SavedVMStateFilePath | New-AzureVM -ServiceName $NewCloudServiceName
Code to move multiple VMs
We can modify above script to move multiple VMs with similar names from one cloud service to another cloud service. In my case the VMs were named like MyProjectVM1, MyProjectVM2… The script will look like below:-
   1: #Step 1 : Declare Variables
   2: $CurrentCloudServiceName = "CurrentService"
   3: $NewCloudServiceName = "NewService"
   4: $StorageAccount = "MyProjectStoarge"
   5: $SubscriptionName = "My Project Subscription"
   6: $VMNamePrefix = "MyProjectVM"
   7: $VMCount = 5
   8: $SavedVMStateFilePath = "E:\XML\"
   9:
  10: #Step 2 : Set Azure Subscription
  11: Set-AzureSubscription -SubscriptionName $SubscriptionName -CurrentStorageAccountName $StorageAccount
  12: Select-AzureSubscription $SubscriptionName
  13:
  14: #Step 3 : Export VMs
  15: for($vmNum = 1; $i -le $VMCount; $vmNum++)
  16: {
  17:     $VMNameToMove = $VMNamePrefix + $vmNum
  18:     $SavedVMStateFilePathFull = $SavedVMStateFilePath + $VMNamePrefix + $vmNum + ".xml"
  19:     Get-AzureVM -ServiceName $CurrentCloudServiceName -Name $VMNameToMove
  20:     Export-AzureVM -ServiceName $CurrentCloudServiceName -Name $VMNameToMove -path $SavedVMStateFilePathFull
  21: }
  22:
  23: #Step 4 (Manual Step) : Edit Azure VM Saved State XML File - Change PowerShell endpoint Public Port (as different VMs should have different public ports)
  24:
  25: #Step 5 : Remove Azure VMs from current cloud service
  26: for($vmNum = 1; $i -le $VMCount; $vmNum++)
  27: {
  28:     $VMNameToMove = $VMNamePrefix + $vmNum
  29:     Remove-AzureVM -ServiceName $CurrentCloudServiceName -Name $VMNameToMove
  30: }
  31:
  32: #Step 6 : Import Azure VMs in new cloud service
  33: for($vmNum = 1; $i -le $VMCount; $vmNum++)
  34: {
  35:     $VMNameToMove = $VMNamePrefix + $vmNum
  36:     $SavedVMStateFilePathFull = $SavedVMStateFilePath + $VMNamePrefix + $vmNum + ".xml"
  37:     Import-AzureVM -Path $SavedVMStateFilePathFull | New-AzureVM -ServiceName $NewCloudServiceName
  38: }

 

Happy Coding!!!

 

Useful Info (Thanks Davis for this note)

If you get some warning like this “New-AzureVM : BadRequest: The virtual network ID cannot be null or empty.”

Is because you have a Site to Site VPN. You need to add -VNetName cmd like this: (include the ” “)

Import-AzureVM -Path $SavedVMStateFilePath | New-AzureVM -ServiceName $NewCloudServiceName -VNetName “NetAzure”


Comments (9)

  1. Dinesh says:

    Hi Sonam,

    It's really helpful for me, Thank you.

  2. MaNISH says:

    Really Appreciate…!

  3. Davis says:

    If you get some warning like this "New-AzureVM : BadRequest: The virtual network ID cannot be null or empty."

    Is because you have a Site to Site VPN. You need to add -VNetName cmd like this: (include the " ")

    Import-AzureVM -Path $SavedVMStateFilePath | New-AzureVM -ServiceName $NewCloudServiceName -VNetName "NetAzure"

    -DvS-

    1. Jeroen says:

      Davis, thanks a lot for explaning how to fix the warning! The Site to Site VPN was indeed the problem. After adding the VNetName in PowerShell it was solved 🙂

    2. Thanks Davis, I have added this as a note in my blog. This info was useful.

  4. Dan says:

    Thank you, this was good, hopefully one day Microsoft can get all these good articles and put them together in an Azure Guide. The information is like a treasure map….

  5. Sheetal says:

    I am following steps as mentioned in blog. But when it comes to
    New-AzureVM I am getting error : ConflictError : a disk with name is currently in use by the VM (VM that was removed by Remove-AzureVM)

    1. Hi Sheetal, you will need to delete the disk explicitly from Azure. It happened because when you deleted VM, you did not deleted the disk.

Skip to main content