Knowledge Base

Helpful Info

VMware created this script to reset CBT in the event of a fault.

			
				# using VMware.VimAutomation.Core
cls
if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null )
{
    Add-PsSnapin VMware.VimAutomation.Core
}
if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null )

{ Write-host "--------------------------------------`nNo PowerCLI Snap-In found.`nPlease install VMWare PowerCLI first`n--------------------------------------" -Backgroundcolor white -ForegroundColor Red 
Write-Host "Press any key to exit and launch a browser to the VMware PowerCLI page."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Start-Process -FilePath "https://my.vmware.com/web/vmware/details?downloadGroup=PCLI550&productId=352"
}
else {
write-host "     _____ ____ _______     _____                _       _______          _ " -foreground green
write-host "    / ____|  _ \__   __|   |  __ \              | |     |__   __|        | |" -foreground green
write-host "   | |    | |_) | | |      | |__) |___  ___  ___| |_       | | ___   ___ | |" -foreground green
write-host "   | |    |  _ <  | |      |  _  // _ \/ __|/ _ \ __|      | |/ _ \ / _ \| |" -foreground green
write-host "   | |____| |_) | | |      | | \ \  __/\__ \  __/ |_       | | (_) | (_) | |" -foreground green
write-host "    \_____|____/  |_|      |_|  \_\___||___/\___|\__|      |_|\___/ \___/|_|" -foreground green
write-host "===============================================================================" -foreground "red"
write-host "This script is provided as-is, no warranty is provided or implied. The author"
write-host "is NOT responsible for any damages or data loss that may occur through the use"
write-host "of this script. This script is free to use for both personal and business use,"
write-host "however, it may not be sold or included as part of a package that is for sale."
write-host "-------------------------------------------------------------------------------" -foreground "red"
write-host "This interactive script will reset CBT for VMs the user specifies.`n"
write-host "Excluding VMs that:" -foreground "red"
write-host "-are powered off"
write-host "-have a snapshot"
write-host "`nThis script will create and remove a snapshot on each VMs that it processes."
write-host "This may temporarily stun the guest OS. You may want to run this off peak hours."
write-host "===============================================================================" -foreground "red"
write-host "Press any key if you understand and wish to continue..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
cls
#Get VMware hostname/ip
$h = read-host "Specify VMware vCenter or ESXi (hostname or ip)"
write-host "`nConnecting to VMware server", $h,"(waiting for logon window)...`n" -foreground "green"
Connect-VIServer $h;
#User will be prompted for login automatically
$ivms = @(); # array of srings for VM names
write-host "`nConnected to server",$h -foreground "green"
write-host "`nSpecify VM to reset CBT for" -NoNewLine
write-host " (do not use wildcards [*])" -foreground "red" -nonewline
$name = read-host " ";
$ivms = $ivms + $name;
while ($name -ne ""){
# Read VM names followed by  until get empty string 
$name = read-host "Specify another VM or leave empty to proceed";
	if ($name -ne "") {	$ivms= $ivms + $name; }
}
$gtvms = @();
$initvms =@(); #initial vms
$povms = @(); #powered on vms
$nspovms = @(); #no snapshot + powered on vms
$powroff = @(); #powered off VMs
$hassnap = @(); #snapshoted VMs
if ($ivms.length -ge 1) {cls}
write-host "Validating list of VMs"
foreach ($vm in $ivms) {
$gtvms = (Get-VM -name $vm)
$initvms = $initvms + $gtvms
}
cls
#Remove Powered Off VMs from selection
write-host "Removing Powered Off VMs from list."
write-host "The amount of time this takes depends on the amount of VMs"
foreach ($vm in $initvms) {
    if ((Get-VM -name $vm).PowerState -ne "PoweredOn") {
        $powroff = $powroff + $vm
		}
	else {
	$povms = $povms + $vm
	}
    }
if($powroff.length -ge 1) {
write-host "`n===============================================================================" -foreground red
write-host "These VMs are powered off, and will not be processed by this script."
write-host "-------------------------------------------------------------------------------" -foreground red
write-host ($powroff | Out-String)
write-host "===============================================================================" -foreground red
write-host "Press any key to proceed excluding the above VMs."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
cls
}
#Remove snapshotted VMs
write-host "Removing Snapshotted VMs from list."
write-host "The amount of time this takes depends on the amount of VMs"
foreach ($vm in $povms) {
    $vmView = $vm | Get-View
    if ($vmView.snapshot -ne $null) {
        $hassnap = $hassnap + $vm
		}
	else {
	$nspovms = $nspovms + $vm
	}
    }
if($hassnap.length -ge 1) {
write-host "`n===============================================================================" -foreground red
write-host "These VMs have snapshots, and will not be processed by this script."
write-host "-------------------------------------------------------------------------------" -foreground red
write-host ($hassnap | Out-String)
write-host "===============================================================================" -foreground red
write-host "Press any key to proceed excluding the above VMs."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
# Function to set options of VM in VMX, takes VM name, key and value
Function Set-ExtraOptions {
	param ([string[]]$vmname, [string[]]$key, $value)
    $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $extra = New-Object VMware.Vim.optionvalue
    $extra.Key=$key
    $extra.Value=$value
    $vmConfigSpec.extraconfig += $extra
        $vm1 = Get-VM -name $vmname | Get-View
        $vm1.ReconfigVM($vmConfigSpec)
		write-host "Reconfiguring",$vmname,"to set",$key,$value
}
cls
write-host "`nFound VMs:" -foreground "green"
foreach ($vm in $nspovms){
Get-Vm -name $vm|Get-View|select name,moref
	foreach ($HardDisk in (Get-VM -name $vm | Get-HardDisk)) {
    write-host $HardDisk.Name,$HardDisk.FileName
	}
}
write-host "`nProceed with resetting CBT for all " -nonewline -foreground "green"
write-host $nspovms.length -nonewline -foreground "green"
write-host " listed VMs? [Y/n]" -nonewline -foreground "green"
$ans = read-host " "
$ans=$ans.ToLower().Trim()[0]
#If user answers Y
if ($ans -eq "y") {
foreach ($vm in $nspovms){
write-host -ForegroundColor Green "`n-------------------------------------------------------------------------------","`nProcessing", $vm,"`n===============================================================================";
$vm1=Get-VM -name $vm | Get-View
# Selecting all VM parameters ending with ctkEnabled for each scsi disk
$opts = $vm1.Config.ExtraConfig | where{$_.Key.EndsWith("ctkEnabled")}
# Where ctkEnabled=true we will set the value to FALSE
	foreach($o in $opts) {
	if($o.Value -eq $true)
		{
		Set-ExtraOptions -vmname $vm -key $o.Key -value FALSE
		}
	}
	write-host "Creating snapshot"
	# Create VM snapshot
	Get-VM -name $vm | New-Snapshot -Name Snapshotcbt -Description "snapshot for cbt reset" | Out-Null 
	write-host "Deleting all snapshots on",$vm 
	# Delete all snapshots
	Get-VM $vm | Get-Snapshot | Remove-Snapshot -Confirm:$false | Out-Null
$vm1=Get-VM -name $vm | Get-View
# Selecting all VM parameters ending with ctkEnabled for each scsi disk
$opts = $vm1.Config.ExtraConfig | where{$_.Key.EndsWith("ctkEnabled")}
# Where ctkEnabled=FALSE we will set the value to TRUE
foreach($o in $opts) { 
    if($o.Value -eq $false){
	Set-ExtraOptions -vmname $vm -key $o.Key -value TRUE
	}
}
write-host "===============================================================================","`nCBT has been reset for ",$vm,"`n-------------------------------------------------------------------------------" -foreground green;
} 
} else { write-host "`nCanceled" }
#Disply Warning if powered off VMs
Disconnect-VIServer -Force -Confirm:$false -Server $h
Write-Host "`n-------------------------------------------------------------------------------`nPress any key to exit..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
#######################################################################