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”
This comment has been removed by a blog administrator.
ReplyDelete