VMware Cloud Community
craigmash
Contributor
Contributor

Shutting down VM's and Host

I have all my VM's set to start/stop automatically. If I Shut Down a host using vSphere Client, it suspends all the VM's then shuts down the host, as expected.

However, I am trying to run a vSphere CLI command to do the same. The problem is, while all of the VM's begin the suspend process, the host shuts down BEFORE it completes the suspension of the VM's and leads to a bad shutdown of all VM's.

Here is the command I am using right now...

"C:\Program Files (x86)\VMware\VMware vSphere CLI\bin\vicfg-hostops.pl" -a suspend --server=<ip> --username <username>--password <password> --operation shutdown --force

Is there something I can do to make it honor my automatic shutdown settings?

0 Kudos
9 Replies
craigmash
Contributor
Contributor

I just did another Shut Down test from vSphere Client and it DID NOT finish the suspension before shutdown. Even though it certainly did in past tests.

Is there a problem with 5.5 and the automatic shutdowns?

0 Kudos
BenLiebowitz
Expert
Expert

I've never done this via vSphere CLI before, I always do it via PowerCLI.  My script is below.

# Get All the ESX Hosts

$ESXSRV = Get-Host -Name "ESXHOST" | Get-VMHost

# For each of the VMs on the ESX hosts

Foreach ($VM in ($ESXSRV | Get-VM)){

    # Shutdown the guest cleanly

    $VM | Shutdown-VMGuest -Confirm:$false

}

# Set the amount of time to wait before assuming the remaining powered on guests are stuck

$waittime = 200 #Seconds

$Time = (Get-Date).TimeofDay

do {

    # Wait for the VMs to be Shutdown cleanly

    sleep 1.0

    $timeleft = $waittime - ($Newtime.seconds)

    $numvms = ($ESXSRV | Get-VM | Where { $_.PowerState -eq "poweredOn" }).Count

    Write "Waiting for shutdown of $numvms VMs or until $timeleft seconds"

    $Newtime = (Get-Date).TimeofDay - $Time

    } until ((@($ESXSRV | Get-VM | Where { $_.PowerState -eq "poweredOn" }).Count) -eq 0 -or ($Newtime).Seconds -ge $waittime)

# Shutdown the ESX Hosts

$ESXSRV | Foreach {Get-View $_.ID} | Foreach {$_.ShutdownHost_Task($TRUE)}

Ben Liebowitz, VCP vExpert 2015, 2016, & 2017 If you found my post helpful, please mark it as helpful or answered to award points.
0 Kudos
BenLiebowitz
Expert
Expert

You said you're trying to shutdown one host so I used the command below. 

$ESXSRV = Get-Host -Name "ESXHOST" | Get-VMHost


However, you can use Get-Datacenter, or Get-Cluster too. 



Ben Liebowitz, VCP vExpert 2015, 2016, & 2017 If you found my post helpful, please mark it as helpful or answered to award points.
0 Kudos
craigmash
Contributor
Contributor

Thanks for the reply. I will certainly look into powerCLI.

However, I am needing this shutdown script to run from a VM on the host that is shutting down when the UPS runs low. (Tripplite UPS) I am worried the VM running the script would be shut down before it completed the script.

0 Kudos
BenLiebowitz
Expert
Expert

Okay, I got ya... and I've been there in the past.  Here's a different script that I've used in that Senario. Replace with your vcenter, replace get-datacenter with get-vmhost and VM12345 with your VM that you're using to run the script.

# Connect to vCenter

Connect-VIServer VCENTER.domain.com

# Gets the list of all VMs in a specific folder

$vms = Get-vmhost -name ESXHOST | Get-VM | where {$_.Name -ne "VM12345" -and $_.PowerState -eq "PoweredOn"}

# Shuts down the VMs in the datacenter that are in a powered on state.

Foreach ($vm in $vms){

  if($vm.ExtensionData.Config.Tools.ToolsVersion -ne "0"){

  #gracefully shutdown

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

  sleep -Seconds 60

  }

  #forcefully stopping VM

  Stop-VM -VM $vm -Confirm:$false

  }

sleep -seconds 120

Shutdown-VMGuest -VM "VM12345" -Confirm:$false

sleep -seconds 120

Get-VMHost -Server (get-vmhost -name ESXHOST) | %{
        
$_.ExtensionData.ShutdownHost_Task($TRUE
)

Ben Liebowitz, VCP vExpert 2015, 2016, & 2017 If you found my post helpful, please mark it as helpful or answered to award points.
craigmash
Contributor
Contributor

I am trying to follow the script (without knowing much about the scripting language). Couple of questions..

Can I suspend the VM's instead of shutdown?

What does "sleep -Seconds 60" and "sleep -seconds 120" do?


So somehow this script will send a signal to shutdown the last VM and the host?


Thank you!

0 Kudos
BenLiebowitz
Expert
Expert

Sure, you can swap out the line below

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

for

Suspend-VM -VM $vm -Confirm:$false

The sleep commands are pauses to wait for the shutdown/suspend task to complete.  In the line that says $vms = Get-vmhost...  the part where it says {$_.Name -ne "VM12345"...  that means to shutdown/suspend all VMs on the host EXCEPT that VM and wait 60 seconds in between.  Then, at the end, it'll wait 2 minutes and then shutdown the VM you're running your script on.  Finally, it'll shutdown the ESX Host itself. 

Ben Liebowitz, VCP vExpert 2015, 2016, & 2017 If you found my post helpful, please mark it as helpful or answered to award points.
craigmash
Contributor
Contributor

So how does it send the command to shut down the host if the last VM is shutting down? Is the whole thing sent to the Host at one time and then it runs it? It does not have to run step by step on the VM that runs the script?

0 Kudos
BenLiebowitz
Expert
Expert

Good point..  You're going to have to send the shutdown host command without sending the suspend the last VM command and hopefully the host can suspend the 1 VM before it shuts itself down. 

When I did this before, I did it from a separate server... 

Ben Liebowitz, VCP vExpert 2015, 2016, & 2017 If you found my post helpful, please mark it as helpful or answered to award points.
0 Kudos