VMware Cloud Community
romain-pierre
Contributor
Contributor

Script stopped with VM question in VC while detaching CD/DVD from VMs

Hi,


I have a script to detach CD/DVD for all VMs running on the specified datastore and print the result if successful or not.

My problem is for one of the VM, the script paused and I have the following "Virtual Machine Message" in vCenter:

"The guest operating system has locked the CD-ROM door and is probably using the CD-ROM, which can prevent the guest from recognizing media changes. If possible, eject the CD-ROM from inside the guest before disconnecting. Disconnect anyway and override the lock?"

The answer could be yes or no but I have to click manually.

How can I insert in my script to continue the process by answering yes or no automatically?

function Detach-CD-DS{
param([string] $Datastore)
$VM = Get-VM -Datastore $Datastore | sort Name
Foreach ($_ in $VM)
     {
          if ($_ | Get-CDDrive | Set-CDDrive -NoMedia -Confirm:$false -WarningAction:SilentlyContinue)
          {write-host "CD/DVD detach ok for VM:"$_.Name}
          else
          {
          write-host "CD/DVD detach failed for VM:"$_.Name
          }
     }
}

2013-03-27_14h16_11.png

The VM is a Cisco VSG VM and has a CD/DVD attached that is connected and that connect at power on  (ISO image is located on the VM folder).

My goal is to move all the VMs running on this datastore to another datastore and I would like to make sure no CD/DVD are attached to them.

I have noticed that when I move this particular Cisco VM to another datastore, the ISO image move at the same time. Not true for other VMs with Media attached to them (e.g. Windows VM with a Windows ISO image attached).

So what I would like is to detach CD/DVD from all VMs and if it's a Cisco VM, answer to the Virtual Machine Message in VC by yes or no for the script to continue.

Thank you for your help.

Reply
0 Kudos
7 Replies
romain-pierre
Contributor
Contributor

The script wait for the an answer to the question in VC.

If I open a new powershell script command window, I am able to answer VM questions with the following command:

get-VM | Get-VMQuestion | Set-VMQuestion -Option "No" -Confirm:$false

(ref: http://www.boche.net/blog/index.php/2012/04/17/using-powercli-to-answer-virtual-machine-message-ques...)

What I would like is to have the script continuing and answering the questions one by one automatically.

function Detach-CD-DS{
     param([string] $Datastore)
     $VM = Get-VM -Datastore $Datastore | sort Name
     Foreach ($_ in $VM)
     {
          if ($_ | Get-CDDrive | Where {$_.ConnectionState.Connected})
          {
          write-host "Detaching CD/DVD for VM:"$_.Name
          $_ | Get-CDDrive | Set-CDDrive -NoMedia -Confirm:$false -WarningAction:SilentlyContinue
          $_ | Get-VMQuestion | Set-VMQuestion -Option "No" -Confirm:$false
          }
          else
          {
               write-host "No CD/DVD attached to VM:"$_.Name
          }
     }
}

My problem is that the script stops and wait for an answer just before I can set up the answer to the question.

And before to run the command to set the CD/DVD to NoMedia, there is no question asked.

How can I script something like:

If (mycommand return question)

     {

          set answer to the question

          run the command

     }

Cheers.

Reply
0 Kudos
coza
Contributor
Contributor

I would like to bump this question as I cannot find an answer to this either.

Reply
0 Kudos
LucD
Leadership
Leadership

Have a look at Answer the question!


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
ITSavant
Contributor
Contributor

LucD

I used your Set-CDDriveAndAnswer function, but since I have to powershell to all my vCenters through firewalls and with AD accounts in different domains for each, I found your version was causing me trouble with the Start-Job call, without adding a section to reconnect to the vCenter with creds. So I offer the following update that allows the operation to succeed sequentially in spite of the need to answer the vCenter question.

Function Set-CDDriveAndAnswer{

  <#

    .SYNOPSIS  Unmounts a CD/DVD from a VM and answers an outstanding question

    .DESCRIPTION The function will unmount a CD/DVD from a DVD.

      If the unmount causes a question, the function will answer the question.

    .NOTES  Authors:  Luc Dekens, David A. Stewart

    .PARAMETER VM

      The DisplayName of the VM

    .PARAMETER Server

      The vSphere Server on which the VM is located.

      The default is $global:defaultviserver

    .EXAMPLE

      PS> Set-CDDriveAndAnswer -VM MyVM -Server $global:DefaultVIServer

    .EXAMPLE

      PS> Get-VM | Set-CDDriveAndAnswer

    #>

      [CmdletBinding()]

      param(

        [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]

        [string[]]$VM

      )

    $objVM = Get-VM $VM

    $vCenter = $objVM | %{$_.Uid.Substring($_.Uid.Indexof('@')+1).split(":")[0]}

    $VMView = $objVM | Get-View

    $driveName = "CD/DVD Drive 1"

    $dev = $VMView.Config.Hardware.Device | where {$_.DeviceInfo.Label -eq $driveName}

    If($dev){

        $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

        $spec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)

        $spec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec

        $spec.deviceChange[0].operation = "edit"

        $spec.deviceChange[0].device = $dev

        $spec.deviceChange[0].device.backing = New-Object VMware.Vim.VirtualCdromIsoBackingInfo

        $spec.deviceChange[0].device.Connectable = New-Object VMware.Vim.VirtualDeviceConnectInfo

        $spec.deviceChange[0].device.Connectable.Connected = "false"

        $spec.deviceChange[0].device.backing.fileName = ""

        $VMView.ReconfigVM_Task($spec)

        $maxPass = 30

        $pass = 0

        while($pass -lt $maxPass){

            $question = ""

            $question = Get-VM $VM -server $vCenter | Get-VMQuestion -QuestionText "*locked the CD-ROM*"

            If($question){

                Set-VMQuestion -VMQuestion $question -Option button.yes -Confirm:$False -ErrorAction SilentlyContinue | Out-Null

            }

            $pass++

            IF(!(Get-VM $VM -server $vCenter | Get-CDDrive)){$pass = $maxPass}

        }

    } 

}

Reply
0 Kudos
LucD
Leadership
Leadership

Nice Smiley Happy


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
ITSavant
Contributor
Contributor

Been testing more. Depending on vCenter version the Answer options for the question have changed, therefore I added a change to capture and use the correct option.

Function Set-CDDriveAndAnswer{
<#
.SYNOPSIS  Unmounts a CD/DVD from a VM and answers an outstanding question
.DESCRIPTION The function will unmount a CD/DVD from a DVD.
   If the unmount causes a question, the function will answer the question.
.NOTES  Authors:  Luc Dekens, David A. Stewart
.PARAMETER VM
   The DisplayName of the VM
.PARAMETER Server
   The vSphere Server on which the VM is located.
   The default is $global:defaultviserver
.EXAMPLE
   PS> Set-CDDriveAndAnswer -VM MyVM -Server $global:DefaultVIServer
.EXAMPLE
   PS> Get-VM | Set-CDDriveAndAnswer
#>
   [CmdletBinding()]
   param(
  [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
  [string[]]$VM
   )

$objVM = Get-VM $VM
$vCenter = $objVM | %{$_.Uid.Substring($_.Uid.Indexof('@')+1).split(":")[0]}
IF($objVM | Get-CDDrive | ?{$_.IsoPath -AND ($_.ConnectionState.Connected -match "True")}){
  $VMView = $objVM | Get-View
  $driveName = "CD/DVD Drive 1"
  $dev = $VMView.Config.Hardware.Device | where {$_.DeviceInfo.Label -eq $driveName}
  If($dev){
   $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
   $spec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)
   $spec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
   $spec.deviceChange[0].operation = "edit"
   $spec.deviceChange[0].device = $dev
   $spec.deviceChange[0].device.backing = New-Object VMware.Vim.VirtualCdromRemoteAtapiBackingInfo
   $spec.deviceChange[0].device.backing.DeviceName = ""
   $spec.deviceChange[0].device.backing.UseAutoDetect = "false"
   $spec.deviceChange[0].device.Connectable = New-Object VMware.Vim.VirtualDeviceConnectInfo
   $spec.deviceChange[0].device.Connectable.Connected = "false"
   $VMView.ReconfigVM_Task($spec)

   $maxPass = 30
   $pass = 0
   Write-Host -NoNewLine "$VM Pass.."
   while($pass -lt $maxPass){
    $question = ""
    $question = Get-VM $VM -server $vCenter | Get-VMQuestion -QuestionText "*locked the CD-ROM*"
    If($question){
     $Option = ($question.Options | ?{$_.Summary -match "Yes"} | Select -ExpandProperty Label)
     Set-VMQuestion -VMQuestion $question -Option "$Option" -Confirm:$False -ErrorAction SilentlyContinue | Out-Null
    }
    $pass++
    Write-Host -NoNewLine "$pass.."
    IF(!(Get-VM $VM -server $vCenter | Get-CDDrive | ?{$_.IsoPath -AND ($_.ConnectionState.Connected -match "True")})){$pass = $maxPass; Write-Host "CD/DVD clear on $VM"}
   }
   IF(Get-VM $VM -server $vCenter | Get-CDDrive | ?{$_.IsoPath -AND ($_.ConnectionState.Connected -match "True")}){Write-Host "CD/DVD still connected on $VM"}
  }
}Else{Write-Host "CD/DVD Not connected on $VM"}
}

Reply
0 Kudos
ToddBertschi
Contributor
Contributor

Thank you for this. I've done a few patches on my vCenters and I just got word that the original function wasn't working. I was about to start digging into fixing the code when I thought I should check back here to see if there were any updates. Thank you for the work. It's working as designed.

Cheers!

Reply
0 Kudos