Migrar VMs de datastore masivamente con PowerCLI

Recientemente por un renovación de storage en una infraestructura VMware tuvimos que migrar de forma masiva un gran número de máquinas virtuales desde una LUN del storage antiguo a varias del nuevo. Dado que era una gran cantidad de VMs todas ellas productivas queríamos hacer el cambio con el menor impacto posible, por lo que me decidí a crear este pequeño script con el que migrar vms de datastore masivamente con PowerCLI de forma secuencial.

Migrar VMs de datastore masivamente con PowerCLI

Requisitos del script

Como apuntaba en la introducción ante todo requeríamos que el rendimiento de las máquinas virtuales del entorno se viera afectado lo mínimo posible y, evidentemente, que no tuvieramos problemas de espacio en ninguna LUN ni nada por el estilo. Es por ello que el script dispone de esta “funcionalidad”:

  • Migración de VMs de forma secuencial: Para evitar posibles problemas en la red o en el rendimiento de las cabinas de origen y destino el script migra VMs una a una. La migración de la siguiente máquina virtual no empieza hasta que la anterior finaliza.
  • Balanceo de máquinas virtuales entre las LUNs destino: Dado que teníamos más de una LUN de destino en la que poner las máquinas virtuales el script migra siempre la VM hacia el datastore más vacío (también funciona con una sola LUN destino).
  • Revisión del espacio libre en las LUNs destino: Evidentemente lo que nunca puede pasar es que el datastore destino se quede sin espacio. Es por ello que antes de iniciar una migración se comprueba que existe espacio en la LUN (contando con una reserva del 10% de espacio libre) y de no haberlo se para el script con un error.

Script para migrar VMs de datastore masivamente con PowerCLI

Ahora que ya está claro lo que obligatoriamente debía hacer el script vamos a ver el código:

############### CONFIGURACION ###############
# Obtenemos la lista de VMs
$Vms = Get-Content C:\Scripts\VMs.txt

# Definimos los datastores de destino
$DestinationDatastores = 'New_Datastore1','New_Datastore2'
#############################################

# Recorremos las VMs
ForEach ($Vm in $Vms) {
    # Determinamos el datastore menos ocupado
    $DestinationDatastore = Get-Datastore -Name $DestinationDatastores | Sort-Object -Property FreeSpaceGB -Descending | Select-Object -First 1

    # Calculamos el 10% del datastore como reserva
    $WarningSpace = $DestinationDatastore.CapacityGB * 0.10

    # Comprobamos que exista espacio en el datastore de destino
    if ((Get-VM $Vm).UsedSpaceGB -gt ($DestinationDatastore.FreeSpaceGB - $WarningSpace)) {
        Write-Error -Message "Espacio disponible insuficiente para mover $Vm a $($DestinationDatastore.Name)" -ErrorAction Stop
    }

    # Movemos la VM
    Get-VM $Vm | Move-VM -Datastore $DestinationDatastore -RunAsync

    # Esperamos a que haya finalizado el movimiento
    Do {
        Start-Sleep -Seconds 30
    }
    While ($(Get-VM -Name $Vm | Get-Datastore | Select-Object -ExpandProperty Name) -notcontains $DestinationDatastore.Name)
}

Como veis tampoco es un script muy extenso, vamos a ver el detalle de lo que hace:

  • 3: Obtenemos el listado de VMs a migrar de un archivo .txt con un nombre de VM por línea. (Podemos extraerlas con Get-VM)
  • 6: Declaramos los datastores en los que alojaremos las máquinas virtuales migradas.
  • 10-30: Recorremos las VMs del archivo una a una.
    • 12: Seleccionamos el datastore menos ocupado.
    • 15: Calculamos el 10% del tamaño total del datastore.
    • 18-19: Comprobamos que exista espacio en el datastore y de no haberlo lanzamos error y finalizamos el script.
    • 23: Migramos la VM de datastore.
    • 26-29: Esperamos hasta que la máquina virtual se haya migrado al datastore de destino.

Conclusión

Y hasta aquí la entrada de hoy, si como yo os enfrentáis en el futuro a una migración de cabina dadle una oportunidad al script o adaptadlo a vuestro gusto, os puede ahorrar mucho tiempo mirando como la barrita de progreso va avanzando :-).

¡Hasta la próxima!

Deja un comentario