VMware Cloud Community
bentech20111014
Contributor
Contributor
Jump to solution

Moving 100+ VMs between Intel and AMD Clusters

And here I thought this was an easy one.

Objective:

  1. 1) Move 100+ VMs from one Cluster to another

  2. 2) Change network the guest is using

  3. 3) Move needs to be fast

Prerequisites:

  1. 1) Ensure LUNs from old Cluster are visible from new Cluster

  2. 2) Ensure proper VLANs are available

  3. 3) Ensure Tools are running

Since vMotion is not an option, a shutdown and startup is required.  I put together the following simple script to shutdown guest; wait until machine is not running and do a Move-VM and Start-VM.

Script:

$vms = Import-CSVC:\Scripts\PowerCLI\CSmoveInput.csv

foreach ($vm in $vms){

      $VMdestination = Get-VMHost $vm.tVMhost

      $Network = $vm.tVLAN

      Get-VM -Name $vm.name | Get-NetworkAdapter | Set-NetworkAdapter -StartConnected:$true -Confirm:$false -NetworkName $Network

      Shutdown-VMGuest -VM $vm.name -Confirm:$false

      while (Get-VMGuest $vm.name | where{$_.State -eq "Running"})

            {

            echo "Machine is Still Running"

            Sleep -Seconds 3

            }

      Write-Host $vm.name is off

      Move-VM -vm $vm.name -Destination$VMdestination

      Start-VM -vm $vm.name

}

Most of the time it works fine but too often I get "The operation is not allowed in the current state."

Is there a better way to ensure the VM is OFF?

Any help is greatly appreciated!

Robert

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Can you try the While-loop like this

$vms = Import-CSVC:\Scripts\PowerCLI\CSmoveInput.csv

foreach ($vm in $vms){

      $VMdestination = Get-VMHost $vm.tVMhost

      $Network = $vm.tVLAN

      Get-VM -Name $vm.name | Get-NetworkAdapter | Set-NetworkAdapter -StartConnected:$true -Confirm:$false -NetworkName $Network
      Shutdown-VMGuest -VM $vm.name -Confirm:$false
      while ((Get-VM $vm.name).PowerState -ne "PoweredOff")

            {

            echo "Machine is Still Running"
            Sleep -Seconds 3
            }

      Write-Host $vm.name is off
      Move-VM -vm $vm.name -Destination$VMdestination
      Start-VM -vm $vm.name

}

The State property returned by the Get-VMGuest cmdlet, returns the state of the VMware Tools on the guest.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
11 Replies
LucD
Leadership
Leadership
Jump to solution

Can you try the While-loop like this

$vms = Import-CSVC:\Scripts\PowerCLI\CSmoveInput.csv

foreach ($vm in $vms){

      $VMdestination = Get-VMHost $vm.tVMhost

      $Network = $vm.tVLAN

      Get-VM -Name $vm.name | Get-NetworkAdapter | Set-NetworkAdapter -StartConnected:$true -Confirm:$false -NetworkName $Network
      Shutdown-VMGuest -VM $vm.name -Confirm:$false
      while ((Get-VM $vm.name).PowerState -ne "PoweredOff")

            {

            echo "Machine is Still Running"
            Sleep -Seconds 3
            }

      Write-Host $vm.name is off
      Move-VM -vm $vm.name -Destination$VMdestination
      Start-VM -vm $vm.name

}

The State property returned by the Get-VMGuest cmdlet, returns the state of the VMware Tools on the guest.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
bentech20111014
Contributor
Contributor
Jump to solution

Luc, thank you again for your help.  It works perfect!

Robert

0 Kudos
stacycarter
Enthusiast
Enthusiast
Jump to solution

LucD -

I know that this is an old discussion, but I have a question regarding this script.  (And forgive me because I'm a PowerCLI noob).  Where do you specify the hostname and portgroup/dvportgroup name in the script?  Is it after the "$vm." in $vm.tVMhost and $vm.tVLAN?  If you want to move the 100+ VMs to several different hosts in a cluster, do you have to run this script several times, each time using a .csv with a different list of VM names?

Thanks!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The script uses a CSV file as input.

The Import-Csv cmdlet reads the file into variable $vms, then we loop through all the rows in $vms.

The $vm variable represents 1 row from the CSV file in the script.

And you address the different columns by using the columnname (tVMHost, tVLAN...) as the propertyname on the $vm variable.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
stacycarter
Enthusiast
Enthusiast
Jump to solution

Ahhh, I see.  The second half of your response cleared it up for me. Thanks for the clarification LucD!

0 Kudos
stacycarter
Enthusiast
Enthusiast
Jump to solution

Going to start testing this script this week.  I noticed that the script changes the network for the VM before shutting it down?  In my scenario, the source cluster and destination cluster will have different network configs (different dvswitches, different dvportgroups).  Not sure that changing the network for the VMs at that point would work since they can't see the new network until they're moved to the new cluster.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That is true, but it depends on what you want to do.

When you change the network, the OS running inside the VM will not be reachable anymore.

On the other hand, the cmdlets that work on the VM virtual HW itself, or through the VMware Tools interface will still work since they don't rely on the VM OS network connectivity.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
stacycarter
Enthusiast
Enthusiast
Jump to solution

I don't mind if the VMs lose network connectivity shortly before shutting down.  Just was not sure if the network/dvportgroup change for the VMs would be successful on the VMware side since the old hosts are not part of that dvswitch and can't see the dvportgroups.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

To be honest I'm not sure if the Set-NetworkAdapter will take a non-existing portgroup. I'll have to try that out.

But you can always create these portgroups temporary on the source cluster if needed, and remove them after the migration.

You don't need to connect any vNICs to these temporary portgroups.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
stacycarter
Enthusiast
Enthusiast
Jump to solution

For my scenario, I modified the script to do the following for each VM:

  • Change dvportgroup for VM to port group on "transfer" dvswitch (Since source and destination dvswitches have different configs, running into the error detailed in the following blog post so created temp "transfer" switch with no uplinks - http://www.v-front.de/2012/02/how-to-smoothly-migrate-vm-from-one-dvs.html)
  • Move VM to destination host
  • Change dvportgroup for VM to the correct port group on destination dvswitch
  • Start VM

Removed the shutting down VMs portion of the script, since in my case the VMs will already be down.  Was thinking I would have to modify the script if any VMs had more than one network adapter, but it looks like I got lucky because all have just one adapter. Tested modified script and it's working.  Would be nice if I could figure out how to modify the loop so that multiple VMs migrate at the same time (or perhaps I just use mulitple command windows, multiple spreadsheets).    -Stacy

$vms = Import-CSV c:\csmoveinput

foreach ($vm in $vms){

      $VMdestination = Get-VMHost $vm.VMhost

      $Network = $vm.VLAN

      Get-VM -Name $vm.name | Get-NetworkAdapter | Set-NetworkAdapter -StartConnected:$true -Confirm:$false -NetworkName dvTransfer
     
      Move-VM -vm $vm.name -Destination $VMdestination
     
      Get-VM -Name $vm.name | Get-NetworkAdapter | Set-NetworkAdapter -StartConnected:$true -Confirm:$false -NetworkName $Network
     
      Start-VM -vm $vm.name

}

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Your best bet to multi-thread the script woud be, imho, to use the Start-Job cmdlet and launch a job for each VM.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos