General DVD script [Hyper-V]

General DVD script [Hyper-V]

  • Comments 1


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:

image

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

Attachment: DVDTools.zip
Leave a Comment
  • Please add 6 and 6 and type the answer here:
  • Post
  • 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.

Page 1 of 1 (1 items)