Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
After digging up and posting my script for connecting an ISO to a virtual machine last week – I decided to spend some time fleshing out that script into a more generic one that allows you to do anything “DVD related” that you could want to do with a virtual machine. I ended up with a script that allows you to select a virtual machine and then choose to either:
- View the current DVD configuration
- Connect an ISO file
- Connect a physical DVD
- Eject the current media
Here is a screen shot of it running on my computer:
And here is the code for the script.
Note – this is a pretty huge script (so large as to break the color coding functionality of the code snippet plug-in that I use with Windows Live Writer) but I have attached a copy of the original to the end of this post. I am not going to write much about the script itself – as it is heavily commented and you should be able to figure out what is going on inside it.
# Function for handling WMI jobs / return values
Function ProcessResult($result, $successString, $failureString)
{
#Return success if the return value is "0"
if ($result.ReturnValue -eq 0)
{write-host $successString}
#If the return value is not "0" or "4096" then the operation failed
ElseIf ($result.ReturnValue -ne 4096)
{write-host $failureString " Error value:" $result.ReturnValue}
Else
{#Get the job object
$job=[WMI]$result.job
#Provide updates if the jobstate is "3" (starting) or "4" (running)
while ($job.JobState -eq 3 -or $job.JobState -eq 4)
{write-host $job.PercentComplete "% complete"
start-sleep 1
#Refresh the job object
$job=[WMI]$result.job}
#A jobstate of "7" means success
if ($job.JobState -eq 7)
{write-host $successString}
Else
{write-host $failureString
write-host "ErrorCode:" $job.ErrorCode
write-host "ErrorDescription" $job.ErrorDescription}
}
}
# Function for ejecting the DVD
Function EjectDVD()
{
# If there is media in the drive - eject it
if ($existingRASD) {
$result = $VMMS.RemoveVirtualSystemResources($VM, @($existingRASD))
ProcessResult $result "The DVD drive has been ejected." "Failed to clear the DVD drive."}
}
# Function for connecting media to the DVD
Function ConnectDVDMedia($media)
{
# Create a new object for a DVD media, connected to the DVD drive
$DVDAllocationCapabilities = (gwmi -computername $HyperVServer -namespace root\virtualization Msvm_AllocationCapabilities `
-filter "ResourceType=21 and ResourceSubType='Microsoft Virtual CD/DVD Disk'").__Path.Replace('\', '\\')
$DVDSettingsData = [wmi](gwmi -computername $HyperVServer -namespace root\virtualization Msvm_SettingsDefineCapabilities `
-filter "GroupComponent='$DVDAllocationCapabilities' and ValueRange=0").PartComponent
$DVDSettingsData.Connection = $media
$DVDSettingsData.Parent = $DVDDrive.__Path
# Add the media to the virtual machine
$result = $VMMS.AddVirtualSystemResources($VM, $DVDSettingsData.GetText(1))
ProcessResult $result "The DVD media has been connected." "Failed to connect the DVD media."
}
# Prompt for the Hyper-V Server to use
$HyperVServer = Read-Host "Specify the Hyper-V Server to use (enter '.' for the local computer)"
# Prompt for the virtual machine to use
$VMName = Read-Host "Specify the name of the virtual machine"
# Get the management service
$VMMS = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService -computername $HyperVServer
# Get the virtual machine object
$VM = gwmi MSVM_ComputerSystem -filter "ElementName='$VMName'" -namespace "root\virtualization" -computername $HyperVServer
# SettingType = 3 ensures that we do not get snapshots
$SystemSettingData = $VM.getRelated("Msvm_VirtualSystemSettingData") | where {$_.SettingType -eq 3}
# Get the first DVD drive in the system
$DVDDrive = $SystemSettingData.getRelated("Msvm_ResourceAllocationSettingData") | where{$_.ResourceType -eq 16} | select -first 1
# Make sure the DVD actually exists
if ($DVDDrive -eq $null)
{write-host "No DVD drive exists on that virtual machine"
exit}
# Setup parameters for main menu prompt
$message = "What do you want to do with the DVD drive?"
$info = New-Object System.Management.Automation.Host.ChoiceDescription "&Display Information", "Display information about the current contents of the DVD drive."
$eject = New-Object System.Management.Automation.Host.ChoiceDescription "&Eject", "Eject the current contents of the DVD drive."
$iso = New-Object System.Management.Automation.Host.ChoiceDescription "Connect &ISO", "Connect an ISO file to the DVD drive."
$physical = New-Object System.Management.Automation.Host.ChoiceDescription "Connect &Physical Disc", "Connect a physical disc to the DVD drive."
$quit = New-Object System.Management.Automation.Host.ChoiceDescription "&Quit", "Exit the DVD Tools script."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($info, $eject, $iso, $physical, $quit)
do
{
# Check to see if there is already media in the DVD drive
$existingRASD = $SystemSettingData.getRelated("Msvm_ResourceAllocationSettingData") | where {$_.Parent -eq $DVDDrive.__Path}
# Ask the user what they want to do with the DVD drive
write-host
$promptResult = $host.ui.PromptForChoice("", $message, $options, 0)
write-host
switch ($promptResult)
{
0 {# Display information
# If there is media in the drive - display key information
if ($existingRASD) {
write-host "Media type: " $existingRASD.ElementName
# Check to see if this is an ISO or a physical disk
if ($existingRASD.caption -eq "ISO Disk Image") {write-host "Media : " $existingRASD.Connection}
# Do some wrangling to get the drive letter for the physical disk case
else {$DiskObject = gwmi Win32_CdromDrive -computername $HyperVServer | where {$_.DeviceID -eq $existingRASD.Connection}
write-host "Media : " $DiskObject.Drive}
}
else {
write-host "No DVD disk is configured."
}
}
1 {# Eject the DVD
EjectDVD
}
2 {# Connect an ISO file
# Prompt for the ISO file to connect
$isoPath = Read-Host "Specify the ISO file to connect to the virtual machine"
EjectDVD
ConnectDVDMedia @($isoPath)
}
3 {# Connect a physical disk
# Prompt for the physical disk to connect
$DiskPath = Read-Host "Specify the Disk file to connect to the virtual machine"
$DiskObject = gwmi Win32_CdromDrive -computername $HyperVServer | where {$_.Drive -eq $DiskPath}
if ($DiskObject)
{EjectDVD
ConnectDVDMedia $DiskObject.DeviceID}
else {Write-Host "Invalid CD / DVD drive letter specified"}
}
}
}
until ($promptResult -eq 4)
Cheers,
Ben
Comments
- Anonymous
May 11, 2010
It's not the length that broke the color-highlighting. It broke on the '' because it treated the second single-quote as a literal -- due to the preceding backslash. The code snippet plugin must not have the proper escaping rules for PowerShell scripts.