If you work in an environment where no one remembers to disconnect their ISO images when done then this script is for you.
This script will report each VM with a connected CD drive and its ISO path, to a CSV file
Also once a specified number of days have passed (assuming this script is run once per day) then the connected ISO is disconnected.
There is an issue with the way in which the script disconnects the CD. When the disconnect request is sent, the VM will pause while vCenter asks if you are sure. There is a workaround that I will go in to at the end.
$CDLookupFile = "c:\temp\CDs.csv" # the script will write a list of VM with CD ISO files
$MaxDaysToKeepCDsMounted = 3 # connected ISO CDs will be removed after this many days.
$LogFile = "c:\temp\DisconnectedCDs.log" # path to log file
$vCenterServer = '' # name of vCenter server
connect-viserver $vCenterServer
# import the csv file of known VMs with CD drives, if it exists
if (test-path $CDLookupFile)
{
$ConnectedCDs = @(import-csv $CDLookupFile)
}else{
$ConnectedCDs = @()
}
# loop through each VM
$VMs = Get-VM
foreach ($VM in $VMs)
{
# check if there is a CD drive connected to an ISO.
$ConnectedCD = Get-CDDrive $VM
if ($ConnectedCD.isoPath)
{
# checking the CSV file to see if this VM is listed.
$RowNum = ($ConnectedCDs | where {$_.VM -eq $VM.name}).RowNum
if ($rowNum)
{
# this VM is already listed
# increase the days detected by 1, then check if days detected is equ to $MaxDaysToKeepCDsMounted
$ConnectedCDs[$RowNum].Days = [int]$ConnectedCDs[$RowNum].Days + 1
if ($ConnectedCDs[$RowNum].Days -eq $MaxDaysToKeepCDsMounted)
{
# time to dismount the CD
$TimeNow = get-date -f "yyyy/MM/dd HH:mm"
$ConnectedCD | Set-CDDrive -NoMedia -Confirm:$False
if ($?)
{
"$TimeNow CD disconnected from " + $VM.name + ", path " + $ConnectedCDs[$RowNum].ISOPath | out-file $LogFile -append
$ConnectedCDs[$RowNum].Days = "deleted"
}else{
"$TimeNow CD failed to disconnect from " + $VM.name + ", path " + $ConnectedCDs[$RowNum].ISOPath | out-file $LogFile -append
}
}
}else{
# this VM is not listed in the CSV add to list
$tmpObj = '' | select vm,ISOPath,DS,RowNum,Days
$tmpObj.VM = $VM.name
$tmpObj.ISOPath = $ConnectedCD.IsoPath
$tmpObj.DS = ((($ConnectedCD.IsoPath).split("]"))[0]).replace("[",'')
$tmpObj.RowNum = $ConnectedCDs.count
$tmpObj.Days = 0
$ConnectedCDs += $tmpObj
} # end of is it in the ConnectedCDs array
} #end of if connected to ISO
} # end of VM loop
# this section of code will reorder the CSV so the RowNum starts at 0
$NewRowNum = 0
$NewConnectedCDs = @()
foreach ($CDRow in $ConnectedCDs)
{
if ($CDRow.days -ne "deleted")
{
$NewConnectedCDs += $CDRow
$NewConnectedCDs[$NewRowNum].RowNum = $NewRowNum
$NewRowNum ++
}
}
$NewConnectedCDs | export-csv $CDLookupFile -NoTypeInformation
How it works
Lines 5 – 11.
Import a CSV, if it does not exist just create the $ConnectedCDs array. This will contain a list of VMs with attached ISOs. also the number of days the ISO has been attached, the ISO path and the datastore.
Lines 14 – 19.
Loop through each VM, check if there is a CD drive pointing to an ISO.
Lines 20 – 24.
Check if this VM with ISO is listed in the CSV file ( $ConnectedCDs array). If it’s not in the array jump to line 44.
Lines 26 – 30.
Increase the days attribute for this VM in the $ConnectedCDs array.
Then check if the days attribute is the same as the $MaxDaysToKeepCDsMounted variable.
Lines 31 – 42
Disconnect the CD. Report to log file if that command was successful or not.
Lines 44 – 55.
First time this VM has been detected. Create a temporary object and populate its data with VM name, ISO path, Datastore name, number of days (0) and row number. Add this object to the $ConnectedCDs array
Lines 60 – 72.
This loop will remove any successfully disconnected VMs from the list. It will also re number the list so the deleted rows will not leave gaps. Then save the new array back to the CSV file.
Now as I mentioned at the beginning the script will suspend the VM as vCenter will ask if you really want to disconnect as the OS has a lock on the CD.
The solution for this problem is a function written by Luc Dekens and David A. Stewart.
The URL is here https://communities.vmware.com/thread/440733
To use Luc and David’s function copy the function code to the beginning of the script.
Then change line 36 to
$VM | Set-CDDriveAndAnswer