Eject all CD-ROMs in a VMware cluster
Every VMware administration knows the following issue - the cluster needs to patched and so the particular nodes need to be rebooted. Fortunately this doesn't bother the users working on the farm becuase the virtual machines can be moved "online" between the cluster nodes.
There might be a little show stopper when ISO images (which aren't saved on the cluster storage) are mounted - e.g. local CD drives. In this case the virtual machine can't be moved and the cluster node won't enter maintenance mode - it is necessary to fix this manually.
Depending on the amount of mounted ISOs, this can take some time - what a pity! I wrote the following PowerShell script to produce relief:
1PowerCLI C:scripts> vim VMISOs.ps1
2
3#Get all virtual machines with mounted ISOs and dismount (if wanted)
4#2013 By Christian Stankowic
5
6##################################################################
7
8#Get array of all Clusters
9$myClusters = Get-Cluster
10
11#Create VMs array
12$VMs = @()
13
14Write-Host "Okay - I'm going to check all VMs whether there are mounted ISO files."
15Write-Host "This will take some time - get yourself some coffee.. ๐"
16Write-Host ""
17
18#Get vms of cluster
19foreach ($cluster in $myClusters) {
20 #Get VMs
21 #$thisVMs = Get-VM
22 $thisVMs = Get-Cluster $cluster | Get-VM
23 $counter=0;
24
25 #Get VM information
26 foreach ($vm in $thisVMs) {
27 #Get view
28 $vmView = $vm | Get-View
29
30 if( (($vm | Get-CDDrive).ISOPath) -or (($vm | Get-CDDrive).RemoteDevice) -or (($vm | Get-CDDrive).HostDevice) )
31 {
32 #Setup output
33 $VMInfo = "" | Select "VM","Host","ISO","RemoteDevice","HostDevice"
34
35 #Write-Host "VM = $vm | Host = " ($vm | Get-VMHost).name " | ISO = " ($vm | Get-CDDrive).ISOPath " / Remote-Device = " $(vm | Get-CDDrive).RemoteDevice " / HostDevice = " $(vm | Get-CDDrive).HostDevice
36
37 #Defining hostname, ESX host and ISO path
38 $VMInfo."VM" = $vm.Name
39 $VMInfo."Host" = ($vm | Get-VMHost).Name
40 $VMInfo."ISO" = ($vm | Get-CDDrive).ISOPath
41 $VMInfo."RemoteDevice" = ($vm | Get-CDDrive).RemoteDevice
42 $VMInfo."HostDevice" = ($vm | Get-CDDrive).HostDevice
43
44 #Add to array
45 $VMs += $VMInfo
46 }
47
48 $counter++;
49 if( $counter % 10 -eq 0 ) {
50 Write-Host "Check $counter of " $thisVMs.length " in " $cluster " so far..."
51 }
52 }
53}
54
55#sort array by Cluster
56$VMs | Sort Cluster
57
58#disconnect
59$answer = Read-Host "Found " $VMs.length " mappings - force disconnect now? (y/n)"
60if($answer -eq "y")
61{
62 foreach ($vm in $VMs)
63 {
64 Write-Host "Disconnect on " $vm.VM "..."
65 Get-VM $vm.VM | Get-CDDrive | Set-CDDrive -NoMedia -Confirm:$false
66 }
67}
68else { Write-Host "Disconnect aborted by user." }
The script requires that PowerShell and VMware PowerCLI are installed. After a connection to vCenter is established, the script asks all clusters and appropriate virtual machines for mounded CD-ROMs/ISOs. Afterwards a list with all affected virtual machines is displays - after that the media is ejected and the administration tasks can continue.
1PowerCLI C:scripts> Connect-VIServer TVM-VCENTER
2
3PowerCLI C:scripts> .VMISOs.ps1
4Okay - I'm going to check all VMs whether there are mounted ISO files.
5This will take some time - get yourself some coffee.. ๐
6
7Check 10 of 136 in Demo-Cluster so far...
8....
9VM : TVM-WEB01
10Host : hypervisor01.localdomain.loc
11ISO :
12RemoteDevice : /usr/lib/vmware/isoimages/windows.iso
13HostDevice :
14
15Found 6 mappings - force disconnect now? (y/n): y
16Disconnect on TVM-WEB01 ...
17...
This helps me a lot before starting administration tasks. ๐