Hi,
I have to migrate 200+ VMs, they are sitting in ClusterA to Cluster B. Here ClusterA ESXi hosts are having one set of VLAN as part of a vDS1 and ClusterB ESXi hosts are having another set of VLANs as part of another vDS2 (None of the ESXi hosts are part of both vDS). Here the requirement is we have to initiate migration for multiple VMs saved in the location: "C:\VMs\VMs.txt" which are in the ClusterA to ClusterB, but during the migration time, I have to select a different VLAN. I have gone through multiple forums and all are saying how to change the VLANs for multiple VMs in the same cluster/esxi hosts.
Can someone please help me on this?
$serverlist = Get-Content "C:\VMs\VMs.txt"
ForEach ($server in $serverlist)
{
$NIC = Get-NetworkAdapter -VM $server
Set-NetworkAdapter -NetworkAdapter $NIC -NetworkName "New VLAN"
}
If different VLANs are available at your environment, then you have to create some kind of mapping, where it maps the source VLAN (old vlan) to the destination one (new vlan).
$vlanMappings = @{
"portgroup_vlan1055" = "portgroup_vlan2055"
"portgroup_vlan1056" = "portgroup_vlan2056"
"portgroup_vlan1057" = "portgroup_vlan2057"
}
then when you call the hash table, by providing the source VLAN you'll get the destination one.
Instead of the example below "portgroup_vlan1055" you have to put the information that you get from the Get-NetworkAdapter and then use the NetworkName property. (check the full code below).
$vlanMappings["portgroup_vlan1055"]
Now you can start writing the script.
I can go something like this:
# Define vlan mappings
$vlanMappings = @{
"portgroup_vlan1055" = "portgroup_vlan2055"
"portgroup_vlan1056" = "portgroup_vlan2056"
"portgroup_vlan1057" = "portgroup_vlan2057"
}
# Define cluster names
$SourceClusterName = "ClusterA"
$DestinationClusterName = "ClusterB"
# Get the destination cluster object.
$destinationCluster = Get-Cluster -Name $DestinationClusterName
# Get the destination VDS
$DestinationVDSwitch = Get-VDSwitch -VMHost ($destinationCluster| Get-VMHost)[0]
# For each VM execute the following code
Foreach($VM in Get-Cluster -Name $SourceClusterName | Get-VM){
# Get the source NetworkAdapter
$SourceNetworkAdapter = $VM | Get-NetworkAdapter
# Find the destination Network Adapter
$destinationPortGroup = Get-VDPortgroup -VDSwitch $DestinationVDSwitch -Name $vlanMappings[$SourceNetworkAdapter.NetworkName]
$vm | Move-VM -Destination $destinationCluster -NetworkAdapter $SourceNetworkAdapter -PortGroup $destinationPortGroup
}
Regarding the mapping variable. That is not written in stone. You can have something like this:
$vlanMappings = @{
"portgroup_vlan1055" = "portgroup_vlan2055"
"portgroup_vlan1056" = "portgroup_vlan2055"
"portgroup_vlan1057" = "portgroup_vlan2057"
}
where two vlans map to one. You can arrange that however you want.
Regarding to move only few VMs at a time / move in batches.
Here you may have different options. One of them is what you mentioned, by exporting the list to a TXT. Another option would be to use Tags. Maybe you have that in place since you mentioned different stages but if not. Create a Tag, and write the script so that it reads the objects tagged with that Tag, and moves them.
When you're done, you remove the tag via PowerCli, and start to Tag the second batch of VMs, and so on.
Which way you chose, is up to you, but there ton of options to do that.
One option would be this one:
# Define the path
$ListOfVMsPath = "C:\VM\VM.txt"
# Read the list of VMs
$ListOfVMs = Get-Content $ListOfVMsPath
# Define the VLAN that will be used
$VLAN = 4000
# Destination Cluster
$DestinationCluster = Get-Cluster -Name "ClusterB"
# Destination port group
$DestinationPortGroup = $DestinationCluster | Get-VMHost | Get-VDSwitch | Get-VDPortgroup | Where {$_.VlanConfiguration.vlanid -eq $VLAN}
# Move each VM to the destination Cluster, destination VLAN
foreach($VM in $ListOfVMs){
$VMObject = Get-VM -Name $VM
$SourceNetworkAdapter = $VMObject | Get-NetworkAdapter
Move-VM -Destination $DestinationCluster -NetworkAdapter $SourceNetworkAdapter -PortGroup $DestinationPortGroup -VM $VMObject
}
I'm not sure what your actual question is.
If the "NewVLAN" depends on which cluster a VM belongs to, you could do a simple test, and change the destination "New VLAN" accordingly.
$serverlist = Get-Content "C:\VMs\VMs.txt"
ForEach ($server in $serverlist)
{
$NIC = Get-NetworkAdapter -VM $server
$cluster = Get-Cluster -VM $server
if($cluster.Name -eq 'ClusterA"){
Set-NetworkAdapter -NetworkAdapter $NIC -NetworkName "New VLAN A"
}
if($cluster.Name -eq 'ClusterB"){
Set-NetworkAdapter -NetworkAdapter $NIC -NetworkName "New VLAN B"
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Here is my ask. First we have to initiate the Migration for the VMs from ClusterA to ClusterB (This is a requirement since ClusterB has new set of ESXi hosts). If we think about the GUI process, then here it is:
> 1. Right click the VM and initiate the Migration
> 2. Select the default option: Change compute resource only
> 3. Select either ESXi host or Cluster level
> 4. Select the Destination Network. Here I have to select the network from the dropdown menu (All VLANs will display here which belongs to ClusterB)
> 5. Select the default option: Schedule vMotion with high priority (recommended)
> 6. Click Finish
Can this be scripted for multiple VMs?
How do you select which Cluster or ESXi node to migrate to?
And how do you select the Portgroup when multiple are available?
You will have to provide that information somewhere.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Here in the GUI operation, for the point number 3, we can select if we need to choose esxi host or the cluster level. And then for the Network selection all networks will display in the dropdown menu. Please see the screenshots
Here I dont not want to migrate All the VMs at the same time. For example, out off 200 VMs, if I have 25 VMs which belongs to the destination VLAN 100, then I will add only that 25 VMs information in the text file: C:\VMs\VMs.txt. And then I will plan to migrate only that 25 VMs via the script. Once done then I will group another set of VMs which belongs to the destination VLAN 200 and then migrate. From GUI, migrating the VM one by one by selecting the destination network is possible. But I am looking for a script to do this task for multiple VMs.
If different VLANs are available at your environment, then you have to create some kind of mapping, where it maps the source VLAN (old vlan) to the destination one (new vlan).
$vlanMappings = @{
"portgroup_vlan1055" = "portgroup_vlan2055"
"portgroup_vlan1056" = "portgroup_vlan2056"
"portgroup_vlan1057" = "portgroup_vlan2057"
}
then when you call the hash table, by providing the source VLAN you'll get the destination one.
Instead of the example below "portgroup_vlan1055" you have to put the information that you get from the Get-NetworkAdapter and then use the NetworkName property. (check the full code below).
$vlanMappings["portgroup_vlan1055"]
Now you can start writing the script.
I can go something like this:
# Define vlan mappings
$vlanMappings = @{
"portgroup_vlan1055" = "portgroup_vlan2055"
"portgroup_vlan1056" = "portgroup_vlan2056"
"portgroup_vlan1057" = "portgroup_vlan2057"
}
# Define cluster names
$SourceClusterName = "ClusterA"
$DestinationClusterName = "ClusterB"
# Get the destination cluster object.
$destinationCluster = Get-Cluster -Name $DestinationClusterName
# Get the destination VDS
$DestinationVDSwitch = Get-VDSwitch -VMHost ($destinationCluster| Get-VMHost)[0]
# For each VM execute the following code
Foreach($VM in Get-Cluster -Name $SourceClusterName | Get-VM){
# Get the source NetworkAdapter
$SourceNetworkAdapter = $VM | Get-NetworkAdapter
# Find the destination Network Adapter
$destinationPortGroup = Get-VDPortgroup -VDSwitch $DestinationVDSwitch -Name $vlanMappings[$SourceNetworkAdapter.NetworkName]
$vm | Move-VM -Destination $destinationCluster -NetworkAdapter $SourceNetworkAdapter -PortGroup $destinationPortGroup
}
Thank you @LucD
Unfortunately the VLAN mapping wont work here. Because taking your example, the IP segment of VLAN-1055 is also existing in VLAN-3055. Also VLAN-2055 may have more than 2 ip segment. But in the destination, VLANs are created based on the IP segment. Meaning it may not be accurate if we map the VLAN. Also I dont want to move all the VMs from ClusterA to B at the same time since they are Prod, Dev, SQL etc. So we need to move them batch by batch depends on the IP segmentation.
So out off 200 VMs if I am taking 25 VMs that has the same IP ranges then I will copy that VMs from the text file (C:\VMs\VMs.txt) and then call that VMs in the script, and will initiate migration to the ClusterB and then I will mention that I need to use the 'VLAN-4000' (destination vlan as an example) and complete the migration.
Do you think this is possible?
Regarding the mapping variable. That is not written in stone. You can have something like this:
$vlanMappings = @{
"portgroup_vlan1055" = "portgroup_vlan2055"
"portgroup_vlan1056" = "portgroup_vlan2055"
"portgroup_vlan1057" = "portgroup_vlan2057"
}
where two vlans map to one. You can arrange that however you want.
Regarding to move only few VMs at a time / move in batches.
Here you may have different options. One of them is what you mentioned, by exporting the list to a TXT. Another option would be to use Tags. Maybe you have that in place since you mentioned different stages but if not. Create a Tag, and write the script so that it reads the objects tagged with that Tag, and moves them.
When you're done, you remove the tag via PowerCli, and start to Tag the second batch of VMs, and so on.
Which way you chose, is up to you, but there ton of options to do that.
One option would be this one:
# Define the path
$ListOfVMsPath = "C:\VM\VM.txt"
# Read the list of VMs
$ListOfVMs = Get-Content $ListOfVMsPath
# Define the VLAN that will be used
$VLAN = 4000
# Destination Cluster
$DestinationCluster = Get-Cluster -Name "ClusterB"
# Destination port group
$DestinationPortGroup = $DestinationCluster | Get-VMHost | Get-VDSwitch | Get-VDPortgroup | Where {$_.VlanConfiguration.vlanid -eq $VLAN}
# Move each VM to the destination Cluster, destination VLAN
foreach($VM in $ListOfVMs){
$VMObject = Get-VM -Name $VM
$SourceNetworkAdapter = $VMObject | Get-NetworkAdapter
Move-VM -Destination $DestinationCluster -NetworkAdapter $SourceNetworkAdapter -PortGroup $DestinationPortGroup -VM $VMObject
}
Hi, I was getting the below error message:
So I have removed and then added this to the script and it started working fine.
I am to migrate VM from ClusterA to ClusterB. Once completed the migration, when I tried to migrate it back to ClusterA from ClusterB, I am getting this message. What do you think?
I can manually migrate the VMs back to ClusterA, but not with the script.
Hi,
Any suggestion @fannol ?
If I may ask, why do you need to move it back to the previous cluster?
That msg. seems to me that there is another task running on ClusterB so it prevents the VM to leave the host on ClusterB.
Right now I am testing this script with Test VMs. And in real all the VMs are in ClusterB. And I want to move those VMs to ClusterA. And then test VMs that I have created on ClusterA. So I was testing that functionality first and it worked. But I am not able to move it back to ClusterA. Is there anyway you can suggest that is that for: That msg. seems to me that there is another task running on ClusterB so it prevents the VM to leave the host on ClusterB.
And I am thinking, why it is allowing the manual migration, but not via script. This is my confusion!
Ohh found the root cause. Its because of DRS.
Why do you need to relocate it back to the prior cluster, if I may ask?
It appears from that message that another process is running on ClusterB, preventing the VM from leaving the host there.