19 January 2011

Re-Registering VMs Removed from Inventory

The cache module on the array controller failed on a host, and ESXi was wasted. The host stopped responding in vCenter, but did not fail hard enough to trigger HA. Most of the VMs on it were still up and their OSes were responsive to ping requests. Eventually we had to remove the host from vCenter. At that point, all VMs registered on it also are removed from inventory.

I grabbed the info for the guests that were in "disconnected" state _BEFORE_ removing the affected host from vCenter, then removed the host, then re-registered VMs and started them as such:
## Script function:  re-register VMs after host removal from vCenter
## Author: vNugglets.com
## Jan 2011

## cluster in which troubled host resides
$strAffectedCluster = "myCluster"

## get array BEFORE removing bad host from vCenter!!! Else, will not be able to get this info in this manner, since disconnected VMs are removed from inventory at that time, too

## get an array of VM .Net View objects where their OverallStatus is "gray"; optimized for low memory consumption
$arrVMsToHandle = Get-View -ViewType VirtualMachine -SearchRoot (Get-Cluster $strAffectedCluster | Get-View).MoRef -Property Name,Parent,LayoutEx.File,Summary.OverallStatus -Filter @{"Summary.OverallStatus" = "gray"}

## get the hosts in the cluster, to be used for re-registering VMs
$arrHostsInAffectedCluster = Get-Cluster $strAffectedCluster | Get-VMHost

## for each set of VM name, parent folder ID, and .VMX file path, add VM to inventory via New-VM cmdlet; add to random host within the cluster
$arrVMsToHandle | Select Name, Parent, @{n="vmxFilePath"; e={($_.layoutex.File | ? {$_.name -like "*.vmx"}).name}} | %{
New-VM -VMFilePath $_.vmxFilePath -VMHost ($arrHostsInAffectedCluster | Get-Random) -Location (Get-VIObjectByVIView $_.Parent) -RunAsync
} ## end ForEach-Object

## start all of the VMs (may cause a boot storm if huge number of VMs -- split up by groups of x VMs as necessary)
$arrVMsToHandle | %{Start-VM $_.Name -RunAsync}

You could also have put the "Start-VM" call inside of the "ForEach-Object" loop (say, before line 19), but that makes the process more linear than quick. This would require the removal of the "-RunAsync" from the "New-VM" call on line 18.

This could come in handy for you someday. Enjoy!