This article is now 6 years old! It is highly likely that this information is out of date and the author will have completely forgotten about it. Please take care when following any guidance to ensure you have up-to-date recommendations.
My vSphere lab is split into two halves - a low power management cluster, powered by 3 Intel NUCs, and a more hefty workload cluster powered by a Dell C6100 chassis with 3 nodes. The workload servers are noisy and power hungry so they tend to be powered off when I am not using them, and since they live in my garage, I power them on and off remotely.
To automate the process, I wanted to write an Orchestrator workflow (vRO sits on my management cluster and is therefore always on) that could safely and robustly shut down the workload cluster. There were some design considerations:
Something to do with the C6100 IPMI implementation and the ESXi driver does not like being woken from standby mode. It’s annoying, but not the end of the world - I can use impitool to power the hosts on from shutdown. If you want to use host standby, there’s a hostStandby and hostExitStandby workflow in the package on github.
I run VSAN on the cluster, so I need to enter maintenance mode without evacuating the data (which would take a long time and be pointless).
All the running VMs on the cluster should be shut down before the hosts attempt to go into maintenance mode.
I want a “what if” option, to see what the workflow would do if I ran it, without actually executing the shutdown - it’s largely for development purposes, but the power down/power on cycle takes a good half hour and I don’t want to waste time on a typo!
The single input for the workflow is the cluster name, as a string. I’ll step through each of the items in the workflow and just give a brief overview - most of the items are from the vCenter or generic libraries, with a few custom steps (in red) of my own.
getClusterByName - this is a custom action I have written that takes a string name of the cluster and returns a VC:ClusterComputeResource object of the cluster.
getAllVMsOfCluster - takes the cluster object and returns an array of VC:VirtualMachines that are hosted by the cluster.
vmsToShutdown - takes the array of VMs and checks if it has any members, if it does it starts the VM shutdown loop. If the array is empty it continues to the next getAllVMsOfCluster.
selectVM - takes the array of VMs and shifts one VC:VirtualMachine object (removes it from the array). It then checks if the VM is powered on and sets a boolean (true/false) vmPoweredOn variable - attempting to power off an already powered off VM will throw an error. The array of VMs is returned with the VM removed, and the VM object itself is also returned.
vmIsRunning? - custom decision checks whether the “whatIf” boolean is true, and whether the vmPoweredOn is true. If “whatIf” is true, or the VM is already powered off, it jumps back to the vmsToShutdown decision.
shutdownVM - takes the returned VM object and attempts a graceful shutdown (using Guest Tools) and waits for the VM to power off before returning to vmsToShutdown. If the graceful shutdown fails, it throws an error and moves to forcePowerOff.
forcePowerOff - takes the returned VM object that has failed to shut down gracefully, and forces it to power off, then returns to vmsToShutdown.
getAllHostSystemsOfCluster - takes the cluster object and returns an array of VC:HostSystems in the cluster.
**hostsToProcess **- custom decision checks if there are any hosts in the array of hosts. If there are no hosts in the array, it moves on.
selectHostForMM - takes the array of hosts and shifts one VC:HostSystem object. Checks the powerState and inMaintenanceMode of the host and returns a boolean value hostInMaintenanceMode - false if the host is powered on and not in maintenance mode. Also returns the array of hosts minus the host that was removed from the array, and the removed VC:HostSystem to process.
**hostInMaintenanceMode? **- custom decision checks if the hostInMaintenanceMode is false and the whatIf is false and returns true, or returns false if either are true.
Enter maintenance mode - takes the returned host system from selectHost and sets it to maintenance mode, with evacuatePoweredOffVms “no” and vsanMode “noAction” to ensure no data or VMs are migrated. Returns to hostsToProcess when the task completes.
getAllHostSystemsOfCluster - retrieves an array of VC:HostSystems again from the cluster object
hostsToProcess - custom decision checks if there are any hosts in the array of hosts. If there are no hosts in the array, it moves on.
selectHostForShutdown - shifts a VC:HostSystem from the array, checks the host powerState is poweredOn and the inMaintenanceMode is true, returns the array of VC:HostSystems with the host removed and a VC:HostSystem object to process
shutdownHost? - checks for whatIf to be false, and shutdownHost to be true, then moves to Shut down host, or skips to hostsToProcess.
Shut down host - shuts down the VC:HostSystem returned by selectHostForShutdown
Send notification - sends an email notification of success
Default error handler - sends an email notification of failure
org.definit.labManagement Package Contents
The package is available on my github page, along with the individual workflows and actions