domingo, 19 de agosto de 2012

Script PowerShell para apagar infraestructura vmWare

Enunciado

Quieres que en caso de corte de suministro eléctrico prolongado las maquinas virtuales de tu infraestructura vmWare se apaguen ordenadamente por grupos y dejando para el final las maquinas mas críticas (los servidores de dominio).

Entorno

En mi caso dispongo de un SAI EATON que puede notifica a un software Intelligent Power Protector que puede lanzar un batch.

Solución

Me baso en el post http://www.virtu-al.net/2010/01/06/powercli-shutdown-your-virtual-infrastructure/ y algunos de los comentarios que allí hacen.
Coloco las maquinas que deben apagarse en varias carpetas o grupos según su importancia.
La idea es lanzar el siguiente script PowerShell desde un batch (powershell script.ps1)
if (!(get-pssnapin -name VMware.VimAutomation.Core -erroraction silentlycontinue)) {
     add-pssnapin VMware.VimAutomation.Core
 }
Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -Confirm:$false 

function ApagaMaquinasCarpeta 
#Ordena el apagado de las $maquinas en un grupo (host, carpeta, cluster,...etc) y espera un $tiempo dado 
{
 write $Carpeta
 $Maquinas=Get-Folder -Name $Carpeta 
 Foreach ($VM in ($Maquinas |Get-VM  )){
      Shutdown del invitado
     $VM | Shutdown-VMGuest -Confirm:$false
 }
 #Bucle esperando que apague
 $Inicio= (Get-Date).TimeofDay
 do {
   sleep 1.0
  $Lapso=(Get-Date).TimeofDay - $Inicio
     $Quedan = $Tiempo - ($Lapso.TotalSeconds)
  write  $quedan
  $numvms = ($Maquinas |  Get-VM | Where { $_.PowerState -eq "poweredOn"} ).count
  write "Esperando que se apaguen $numvms VMs o que transcurran $Quedan segundos"
  } until ((@($Maquinas |  Get-VM | Where { $_.PowerState -eq "poweredOn"} ).count -eq 0) -or ($Lapso).TotalSeconds -ge $Tiempo)
 write "Maquinas apagadas o plazo consumido ($Lapso)"
}
 clear 
$VCenter= "vcenter.empresa.org"
 
Connect-VIServer $VCenter
$Hosts= Get-VMHost
$Tiempo=1
$Carpeta= "Apagado Directo"
ApagaMaquinasCarpeta 
$Tiempo=20
$Carpeta= "Escritorios"
ApagaMaquinasCarpeta 
$Tiempo=300
$Carpeta= "Servidores"
ApagaMaquinasCarpeta 
$Tiempo=300
$Carpeta= "Ultimo apagado"
ApagaMaquinasCarpeta 
$ESXSRV = Get-VMHost
$ESXSRV | Foreach {Get-View $_.ID} | Foreach {$_.ShutdownHost_Task($TRUE)}
Disconnect-VIServer -server $VCenter -Confirm:$false
write "Fin"
#Apago la estación IPP
Stop-Computer

Comentarios

Eaton suministra un modulo para instalar en la infraestructura, pero me gusta mas esta solución porque puedo verla, probarla y guardar un archivo de seguimiento (redireccionando powershell).

Alguien se preguntará el por qué no uso parámetros de función en lugar de variables globales: no funcionaban, tenia prisa y trabajar con mandatos del tipo shutdown me pone muy nervioso.
En primer lugar porque un error te tira todas las maquinas, pero también porque la actualización ESXi 5.0 me había dejado sin módulos de shutdown, en el agosto mas caluroso desde hace años y podían producirse cortes de suministro por el elevado consumo de aire acondicionado.

No hay comentarios: