Alle CD-Laufwerke eines VMware-Clusters auswerfen
Jeder VMware-Administrator kennt es - der Cluster soll gepacht werden und die einzelnen Nodes müssen nacheinander neugestartet werden. Glücklicherweise besteht für den Endanwender keinerlei Handlungsbedarf, da die virtuellen Maschinen reibungslos zwischen den einzelnen Clusterknoten "online" verschoben werden können.
Einen kleinen Show-Stopper erlebt man dann, wenn auf den virtuellen Maschinen noch ISO-Abbilder, die nicht auf dem gemeinsamen Cluster-Speicher abgelegt wurden, eingehängt sind (beispielsweise lokale CD-Laufwerke). In diesem Fall lässt sich die VM nicht verschieben und der Clusterknoten wechselt nicht in den Wartungsmodus, manuelle Interaktion ist notwendig.
Das kann, je nach Anzahl der ISOs, die eingehängt wurden, Zeit und Nerven kosten. Abhilfe schafft das folgende kleine PowerShell-Skript, welches ich für diesen Zweck geschrieben habe:
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." }
Das Skript erfordert eine installierte PowerShell und VMware PowerCLI. Nachdem eine Verbindung zum vCenter hergestellt wurde, fragt das Skript alle Cluster und alle darin hinterlegten virtuellen Maschinen nach eingehängten CD-ROMs/ISOs ab. Anschließend wird eine Liste der betroffenen VMs angezeigt - nach einer Bestätigung werden die Medien ausgehängt, damit die Administrationsaufgaben ausgeführt werden können.
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...
Insbesondere vor Wartungsarbeiten spart mir das Skript viel Zeit. 🙂