Maintenance mode on ESX hosts is great. As long as DRS is set to automatic and VMotion is working, all of the VM’s will be evacuated from the host. However, I always seem to run into one VM that still has a CDROM drive connected to it. This causes the VMotion to stop until the CDROM drive is disconnected.
Since, this happened quite frequently, I decided to do maintenance mode through PowerShell to automate the process
. The below script will:
- Search for any VM’s that have CDROM’s connected
- Disconnect the CDROM’s from said VM’s
- VMotion the VM’s to the remaining ESX hosts (there is no way that I know of to automatically VMotion the VM’s by just putting the host into maintenance mode using PowerShell)
- Put the target host into maintenance mode
A special thanks goes to Steve Beaver. His post “Working with Maintenance Mode in PowerShell” helped me figure out the automatic VMotion to the remaining hosts.
So, here it is:
# Name: esx-maintenance-prep.ps1
# Purpose: Disconnects all CDROM Drives on VM's from a chosen host. It will VMotion the
# VM's on that host. Then, it will put the host into maintenance mode.
#
# Created: 09/11/2009
# Author: Harley Stagner
# Version: 1
#
# TODO:
# -Wrap work into functions
# -Use if statement to account for VM's that are powered off
################################################################
#Connect to your vCenter Server
Connect-VIServer
Write-Host "Choose your server from the list below:"
# Set up variables for the Host Selection
$colESX = Get-VMHost
$selectionNumber = 0
#HashTable
$colHostSelection = @{}
#Array
$colSelection = @()
# Create the menu choices for the hosts
$colESX | sort Name | ForEach-Object {
$selectionNumber = $selectionNumber + 1
$colHostSelection.Add("$selectionNumber", "$_")
Write-Host "$selectionNumber - $_"
}
# Needed to match the option for the switch statement
$colHostSelection.Keys | ForEach-Object{
$colSelection += $_
}
# Have the VM Admin make the host selection
$VMHostSelection = Read-Host "Please choose an option between" $colSelection[0] "and" $colSelection[-1]
$VMHost = $colHostSelection[$VMHostSelection]
# Switch statement to get the appropriate host to put into maintenance mode.
switch ($colSelection[0]..$colSelection[-1]){
{$_ -eq $VMHostSelection} {
# Disconnect the CDRom Drives from the VM's.
Get-VMHost $VMHost | Get-VM | Get-CDDrive | Set-CDDrive -Connected $false -Confirm:$false
ForEach ($ESX in $colESX){
If ($ESX -cnotmatch $VMHost){
# vMotion the VM's to the other hosts in the cluster.
Get-VMHost -Name $VMHost | Get-VM | Move-VM -Destination (Get-VMHost $ESX)
}
}
# Put the chosen host into Maintenance Mode.
Get-VMHost -Name $VMHost | Set-VMHost -State Maintenance | ForEach-Object { "Entering maintenance mode on '" + $VMHost + "'"} ; continue
}
}
Disconnect-VIServer -Confirm:$False
#END SCRIPT#
As you can see, I still have a couple items in my to do list for this script. However, it is very useable as it stands.


{ 3 comments… read them below or add one }
NiceScript!!! Nice when we can all contribute things to be able to help each other out!!
Cheers,
Steve
Thank you Steve! Thanks for reading and thank you again for the help with the VMotion piece.
Regards,
Harley Stagner
Thank you very much for sharing. This is very useful.