Automation

 View Only
Expand all | Collapse all

How to Keep or Disgard the UUID when powering on a VM

  • 1.  How to Keep or Disgard the UUID when powering on a VM

    Posted Nov 21, 2008 11:40 AM

    We have a scenario where we are mirroring VMs from one site to another site for BCP that has a separate VC instance.

    We are pre-registering the NFS hosted VMs in virtual center.

    When we need to do the recovery we break the mirror and power on the machines.

    VC then promp with the question, Do you want to Keep or Discard the UUID.

    How can this be scripted as its easy to answer for a few VMs but a pain for possibly up to a hundred?



  • 2.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Nov 21, 2008 02:55 PM

    Here is the SDK method to get you started.

    PS > $a = Get-VM myvm | Get-View
    PS > $a | gm *answer*
    
       TypeName: VMware.Vim.VirtualMachine
    
    Name     MemberType Definition
    ----     ---------- ----------
    AnswerVM Method     System.Void AnswerVM(String questionId, String answerChoice)



    [PowerShell MVP|https://mvp.support.microsoft.com/profile=5547F213-A069-45F8-B5D1-17E5BD3F362F], VI Toolkit forum moderator

    Author of the upcoming book: Managing VMware Infrastructure with PowerShell

    Co-Host, PowerScripting Podcast (http://powerscripting.net)

    Need general, non-VMware-related PowerShell Help? Try the forums at PowerShellCommunity.org



  • 3.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Nov 21, 2008 03:02 PM

    Going further, here's the page in the SDK: http://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/vim.VirtualMachine.html#answer

    It's not very helpful. So, I searched for data objects and found QuestionInfo. Hmm. I don't have any VMs with questions right now to look at as an example. Ok, here's what the question would be if I had one--yours should have it:

    $a.Runtime.Question

    So look at that, and you should be able to come up with the question ID and choice to then provide to the AnswerVM() method.






    [PowerShell MVP|https://mvp.support.microsoft.com/profile=5547F213-A069-45F8-B5D1-17E5BD3F362F], VI Toolkit forum moderator

    Author of the upcoming book: Managing VMware Infrastructure with PowerShell

    Co-Host, PowerScripting Podcast (http://powerscripting.net)

    Need general, non-VMware-related PowerShell Help? Try the forums at PowerShellCommunity.org



  • 4.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Jan 16, 2009 02:02 PM

    Sorry to sound a bit thick :smileyhappy: (but I am).

    But could someone provide some example code on how to receive the question and then submit the answer. I have a similar issue with replicated Datastores and controller changes from BUS to LSI logic etc. And have the PowerShell answer the question (as it only happens when the machine tries to boot) would make life far more robust.

    Any help would be much appreciated.

    If I do find the answer myself - I'll post as well.

    TG



  • 5.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Jan 18, 2009 02:19 AM

    Receiving the question(s) can be done like this

    Get-VM | Get-View | %{
      if ($_.Runtime.Question -ne $null){
       Write-Host -foregroundcolor blue "==>" $_.Name 
       Write-Host -foregroundcolor blue $_.Runtime.Question.Id
       Write-Host $_.Runtime.Question.Text
       foreach($choice in $_.Runtime.Question.Choice.ChoiceInfo){
         Write-Host -foregroundcolor green $choice.Key $choice.Summary
       }
    }
    

    Answering the question via a script is a bit more tricky.

    Not the method how you can answer but the algorithm you would use to make a selection from the valid answers.

    It would be dangerous (in my opinion) to always go for the same answer for the same question id.

    Once you know the reply giving the answer to the question is straight forward

    Get-VM | Get-View | %{
      if ($_.Runtime.Question -ne $null){
        $_.AnswerVM($_.Runtime.Question.Id, <selected-choice-key>)
    }
    

    The question id for a SCSI controller change from Bus to Lsi logic is always 4.

    It could be handy to foresee answers to the different questions (see property Question.Id) that are possible.

    That could for example be done via a switch statement.

    I wasn't able to find a list of all the possible question ids.

    If someone could provide a pointer ?



  • 6.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Jan 18, 2009 05:38 PM

    Mr LucD, you are quick. Your's is much more elegant, but this is what I came up with: http://professionalvmware.com/2009/01/18/answering-vm-questions-with-powershell/

    -Cody Bunch

    http://professionalvmware.com



  • 7.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Jan 19, 2009 10:19 AM

    Hi Both,

    Well - I'm glad I took the time to post. Both of you have provided exactly what I needed.

    Many many thanks, You've saved me hours :smileyhappy:

    TG



  • 8.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Jan 23, 2009 01:50 PM

    Hi,

    We were faced with the same problem but did not want to provide any interactive input during startup.

    So we decided to simply set the extraConfig entry for 'uuid.action' to 'keep' in all the VMs before starting them.

    That way, it never asks - and you can always set the value back to 'create' if you need to.

    Just thought you might like another option.

    Thanks



  • 9.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Mar 03, 2009 03:22 PM

    I've only had a chance recently to look at this again.

    Thanks again LucD for a great script.

    However I've come across a scenario where I need some more help.

    The script I'm working on is to automate bringing up VMs mirrored from primary site to a BCP site.

    I have everything done so that the storage breaks the mirror and the iSCSI LUNs are presented and the VMs found and added to the inventory. (I'll post the script when I've finished)

    Now the problem comes with the UUID. There is no question available to answer until you actually power a VM on.

    Problem is once you power a group of VMs on in a script the script will wait for the answer before continuing which means I can't answer the question until I've powered the VMs on but the script won't continue until I answer the question. (If that makes any sense)

    I've cut down the rest of the script and this is what I would like to happen:

    $vmfolder = "BCP Servers" # Folder to place found VMs - Must be unique in VC

    #Get all VMs in $vmfolder

    $vms = get-vm -Location (get-folder $vmfolder)

    #Answer Question to Keep UUID

    $vms | Get-View | %{if ($_.Runtime.Question -ne $null){$_.AnswerVM($_.Runtime.Question.Id, 2)}}

    #Power on VMs

    $vms | Start-VM

    Unfortunately #Answer Question to Keep UUID does not return anything at this stage and so when Start-VM initialises it still has the questions to answer but I can't power on the VMs first as the script pauses waiting for my answer.

    I've tried a few different ways of combining the statements but can't seem to find the right one.

    Something like this

    #Power on VMs and Answer Questions

    $vms | Start-VM | Get-View | %{if ($_.Runtime.Question -ne $null){$_.AnswerVM($_.Runtime.Question.Id, 2)}}How can I group the power on and answer into one statement which would work on a group of VMs?

    Any ideas?



  • 10.  RE: How to Keep or Disgard the UUID when powering on a VM
    Best Answer

    Posted Mar 03, 2009 07:01 PM

    There are a few things to keep in mind when you want to start the guests and answer the question this way.

    1) The Start-VM cmdlet will wait for the guest to be started but since there is a pending question this will never happen.

    ==> the solution is to use the Start-VM cmdlet with the -RunAsync parameter, that way the cmdlet will not wait.

    2) When a guest starts it will take some time before the question appears.

    ==> the solution is to wait with a loop till the question appears

    3) to get the actual state of the guest the script needs to get the VirtualMachine object with every run through the loop.

    The properties in the $vm variable are not automatically updated unless the script fetches the object again with the Get-View cmdlet.

    4) the Question object is only present when the question appears. Before that point this object is $null.

    ==> to avoid executing the StartsWith method on an $null object the if statement first checks if the Question object is present.

    The script relies on the fact that the two conditions that are combined with -and operator are executed left to right.

    This is probably not a good programming practice and should be solved by using two nested if statements !

    The following script implements all the points raised above.

    Note that it can only be used for the msg.uuid.moved question.

    The script answers with choice 2 which is the "Keep" choice.

    $qMsgUuidMoved = "msg.uuid.moved:"
    $choiceKeep = 2
    
    $vmImpl = Get-VM "TestPC"
    $vmImpl | Start-VM -RunAsync
    
    do{
      $vm = $vmImpl | Get-View
      if($vm.Runtime.Question -ne $null -and $vm.Runtime.Question.Text.StartsWith($qMsgUuidMoved)){
        $vm.AnswerVM($vm.Runtime.Question.Id, $choiceKeep)
      }
    } until ($vm.Runtime.PowerState -ne "poweredoff")
    
    Write-Host $vm.Name "started"
    



  • 11.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Mar 06, 2009 02:39 PM

    LucD, as usual that is excellent.

    I will post separately when I have the complete script to share what I have come up with.

    It will be two scripts. One to create consistent VM and mirror them to a remote site and the second script to recoer the VMs in the remote site. Think of it has SRM for free!



  • 12.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Apr 23, 2009 11:26 AM

    Oops, I didn't actually post the script that all worked.

    I'll write another post for the mirroring script but here's the easy way to power on all VMs in a folder and answer the question.

    Can't ever seem to get this quoting thing right especially with indents...anyway

    1. Get All VMs in pariticular VC folder

    $vms = get-vm -Location (get-folder "BCP Servers")

    1. Disconnect Networking if required FOR TESTING ONLY

    $vms | get-networkadapter | where {'ext_vswitch1' -contains $_.NetworkName} | Set-NetworkAdapter -StartConnected:$false -Confirm:$false

    1. Power on VMs even with questions pending

    $vms | Start-VM -RunAsync

    $qMsgUuidMoved = "msg.uuid.moved:"

    $choiceKeep = 2

    ForEach ($vm in $vms)

    {do

    {

    $vmview = $vm | Get-View

    if($vmview.Runtime.Question -ne $null -and $vmview.Runtime.Question.Text.StartsWith($qMsgUuidMoved))

    {

    $vmview.AnswerVM($vmview.Runtime.Question.Id, $choiceKeep)

    }

    }

    until ($vmview.Runtime.PowerState -ne "poweredoff")

    }



  • 13.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Apr 24, 2009 08:48 AM

    Hi all, thought the following code may help others who are trying to get VMDK's to attached to one VM that were created on another. It helps by answering NO to the question "Do you want to change the disk controller type" at bootup. Note - this code seems quite long, but I'm a beginner and I like to write where I can see exactly what's happening, so you will note a LOT of Write-host statements, feel free to remove if you like.

    $sPowerOnMsg = "msg.disk.adapterMismatch:"

    $sWinProxy = "VCB_Proxy"

    $iChoice = 1 # choice of 1 does NOT change the disk type (choice of 0 does) If you do NOT change (ie - 1) then the question will re-occure each time you boot the VM.

    $iVMRestartTimeout = 200

    $oWinVM = Get-VM -name $sWinProxy -ea silentlycontinue

    $oWinVMv = $oWinVM | get-view

    1. Restart the Proxy VM.

    if ($oWinVM.PowerState -eq "PoweredOff")

    {

    Write-host "VM is Powered Off - Restarting VM : " $sWinProxy

    $oWinVM | Start-vm -RunAsync

    write-host "started"

    Do

    {

    sleep 10

    $iVMRestartTimeout = $iVMRestartTimeout - 10

    if ($iVMRestartTimeout -lt 0) {throw "Timeout Error Restarting Proxy VM : $sWinProxy"}

    #Recheck the VM state

    $oWinVM = Get-VM -name $sWinProxy

    $oWinVMv = $oWinVM | get-view

    if($oWinVMv.Runtime.Question -ne $null -and $oWinVMv.Runtime.Question.Text.StartsWith($sPowerOnMsg))

    {

    Write-host $oWinVMv.Runtime.Question.ID

    Write-host $oWinVMv.Runtime.Question.Text

    Write-host "ProxyVM Asked weather to change DIsk Types, Answering NO ($iChoice)"

    Write-host "ANSWERING QUESTION with answer $iChoice"

    $oWinVMv.AnswerVM($oWinVMv.Runtime.Question.Id, $iChoice)

    }

    $sPowerState = $oWinVM.PowerState

    Write-host "Sleeping, Timeout is currently $iVMRestartTimeout, PowerState is $sPowerState"

    } until ($oWinVM.PowerState -eq "PoweredOn")

    }

    elseif ($oWinVM.PowerState -eq "Suspended")

    {

    Write-host "VM is in a Suspended State : " $sWinProxy

    throw "Proxy VM is in a suspended state, please shutddown th VM and re-run script: $sWinProxy"

    }

    else

    {

    Write-host "VM is already in a Powered on state : " $sWinProxy

    throw "Proxy VM is already powered on, please shutddown th VM and re-run script: $sWinProxy"

    }

    Write-host "Proxy is Powered on : " $sWinProxy

    Hope this helps someone :smileyhappy:



  • 14.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted May 28, 2010 09:13 AM

    Hi LucD,

    With vSphere 4 update 1, I know there is a new Set-VMQuestion cmdlet but I could not configured it correctly,

    Your script can also be used for the "msg.uuid.altered:" question with vSphere update1 .

    And the script worked great.

    Robert



  • 15.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted May 28, 2010 09:48 AM

    That is correct Robert.

    Did you try something like this

    Get-VM <VM-name> | Get-VMQuestion -QuestionText "*UUID*" | Set-VMQuestion -Option "Ok"
    

    You have several options for the reply, you can go for the -DefaultOption parameter or you can select a specific answer with -Option where you will have to provide a string with the answer (e.g. "ok", "cancel"...)

    ____________

    Blog: LucD notes

    Twitter: lucd22



  • 16.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Jun 11, 2011 03:45 PM

    Hi LucD,

    Have used your script serveral times and with datacenter migrations for unknown reason, sometimes a vm loses the path to datastores, and when powered-on with the original script in a loop with serveral vm's, the script is wating for that corrupt vm. (Can also be simulated by editing vmx to non existing vmdk).

    I am learning PowerCLI and now modified it see below with some error handeling so it continues and create a errorfile with vmname.

    By the way great book " PowerCLI Reference"  :smileyhappy:

    Regards Robert.

    ##################################
    # Declare global and static variables
    # VMware VirtualCenter server name
    #################################
    CLS
    $vcserver="xxx"
    $Inputfile = "c:\Input_scripts\Servers.txt"
    $TaskErrorFile = "c:\ErrorLog\TaskError.txt"
    $TaskError_VMname = "c:\ErrorLog\TaskErrorVMname.txt"

    # For ESX 3.5x "msg.uuid.moved:"
    #$qMsgUuidMoved = "msg.uuid.moved:"

    #For ESX 4.x "msg.uuid.altered:"
    $qMsgUuidMoved = "msg.uuid.altered:"
    $choiceKeep = 2

    #################
    # Add VI-toolkit
    #################
    Add-PSsnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue


    Connect-VIServer $vcserver -User yyy -Password zzz


    # *************   Start Process   *********************************************

    foreach ($vmname in Get-Content $Inputfile)
    {

    $vmImpl = Get-VM $vmname
    # Note -RunAsync does not work with -ErrorVariable
    $vmImpl | Start-VM -ErrorVariable StartError -ErrorAction:SilentlyContinue
    If ($StartError) {
    # Create output file for working with
    Write-Output $StartError | Out-File $TaskErrorFile

    # Get data and create variable with line that contains VirtualMachine*
    $ErrorData = Get-Content $TaskErrorFile | Select-String -Pattern "VirtualMachine" -SimpleMatch
    $ErrorData = $ErrorData.Line

    # Create Array from data and filter for vm_id
    $vm_ID = ($ErrorData).Split(" ") | where { $_ -match "VirtualMachine*"}

    #Get vm properies for VMname and create errorfile with VMname which failed to start
    $VM = Get-VM -Id $vm_ID
    Write-Output $VM.Name | Out-file $TaskError_VMname

    #Remove temp file(s)
    Remove-Item $TaskErrorFile
    }
    Else {
    do{
      $vm = $vmImpl | Get-View
      if($vm.Runtime.Question -ne $null -and $vm.Runtime.Question.Text.StartsWith($qMsgUuidMoved)){
        $vm.AnswerVM($vm.Runtime.Question.Id, $choiceKeep)
      }
    } until ($vm.Runtime.PowerState -ne "poweredoff")

    Write-Host $vm.Name "started"
    }


    }
    # *************   End Process   ***********************************************
    DisConnect-VIServer -confirm:$false -Force:$true



  • 17.  RE: How to Keep or Disgard the UUID when powering on a VM

    Posted Jun 11, 2011 06:24 PM

    Thanks Robert.

    Great script, thanks for sharing.