BrentCocjhran
Contributor
Contributor

Change Boot Sequence with new Extensiondata option

Hello PowerCLI masters,

I'm attempting to change the boot order for a VM (or a bunch of VMs) with the new Extensiondata.Config.Bootoptions.  Easy enough to edit these values but i'm having some issues determining what the values shoudl be.  I've tried some of the values we used to use and it's failing to take the change.

$vm.Extensiondata.Config.Bootoptions.BootOrder = "Ethernet0"

$vm.Extensiondata.Config.Bootoptions.BootOrder = "Ethernet0,ide0:0"

etc.

Can someone provide some guidance on how to make the appropriate changes?

Thanks!

Brent

10 Replies
LucD
Leadership
Leadership

Have a look at my Specify the boot devices for a virtual machine document.

It's an older doc but the values still work.


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

0 Kudos
BrentCocjhran
Contributor
Contributor

Thank you sir, but I was really hoping for a simpler solution.  It appears that VMware has tried make this a bit easier by adding a property that should be easy to change with one line of code.  For example, to change the boot delay (which we know is in milliseconds):

     PS C:\> $vm = get-vm -name whatever

     PS C:\> $vm.Extensiondata.Config.Bootoptions

     BootDelay        : 1000
     EnterBIOSSetup   : False
     BootRetryEnabled : False
     BootRetryDelay   : 0
     BootOrder        :
     DynamicType      :
     DynamicProperty  :

     PS C:\> $vm.Extensiondata.Config.Bootoptions.BootDelay = 0
     PS C:\> $vm.Extensiondata.Config.Bootoptions


     BootDelay        : 0
     EnterBIOSSetup   : False
     BootRetryEnabled : False
     BootRetryDelay   : 0
     BootOrder        :
     DynamicType      :
     DynamicProperty  :

Pretty easy stuff looks like.  I was hoping to just add a line to existing scripts like: $vm.Extensiondata.Config.Bootoptions.BootOrder = "allow:net,hd,cd"  It seems like that ought to work if I can get the right data format to drop in there.  If i'm on completely the wrong track here, please let me know though.

Thanks!

BC

0 Kudos
LucD
Leadership
Leadership

I'm afraid that will not work.

The ExtensionData properties are in fact copies of the actual objects that exist in the vSphere environment.

To change a setting in those objects, you will have to call a method, ln this case the ReconfigVM_Task method.


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

0 Kudos
mattboren
Expert
Expert

Hello, BrentCocjhran-

Unfortunately, it is not as easy as you are hoping.  The example that you gave of changing the BootDelay value is only changing that property's value on the client-side object "$vm" that you retrieve from the server via Get-VM (a "VirtualMachineImpl" object).  If you were to retrieve another copy of the VM object by calling Get-VM again _after_ you "set" BootDelay to 0 and then listed the values of the BootOptions property by calling "$vm.Extensiondata.Config.BootOptions" again, you will see that "BootDelay" is back to the original value of 1000 -- setting the value on the client-side object does not affect the server-side object.  That is why there is the need to use the ReconfigVM_Task() method to act upon the _server-side_ object.

For example, to actually set the BootDelay value on the server-side VM object, you would use:

## set the BootDelay BootOption on the VM on the server side (not just on the client-side object)
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec -Property @{
    BootOptions
= New-Object VMware.Vim.VirtualMachineBootOptions -Property @{"BootDelay" = "1000"}
}
## end new-object
$vm = Get-VM myVM
## actually reconfig the VM
$vm.ExtensionData.ReconfigVM_Task($spec)

As for the boot sequence task, like LucD said, you can use the ExtraConfig items to set which boot devices from which the VM may try to boot.

Another option is to manage the new BootOrder property of the VM's VirtualMachineBootOptions.  The BootOrder property is new since vSphere API 5.0.  Again, though, you cannot just set its values on the client-side object.  And, the property does not just accept String values -- you have to provide it with actual objects that correspond to given VirtualNetworkCard devices or VirtualDisk devices on the VM.

Here is an example of setting the BootOrder of a VM to be "Network adapter 1", "Hard disk 1", CD (the specification uses the device Keys of the NIC and hard disk -- see the comments in the code):

## the VM to configure
$strVMName = "myVM"
## the device name of the NIC to which to boot
$strBootNICDeviceName = "Network adapter 1"
## the device name of the hard disk to which to boot
$strBootHDiskDeviceName = "Hard disk 1"
## get the VM object
$vm = Get-VM $strVMName

## get the VirtualEthernetCard device, and then grab its Key (DeviceKey, used later)
$intNICDeviceKey = ($vm.ExtensionData.Config.Hardware.Device | ?{$_.DeviceInfo.Label -eq $strBootNICDeviceName}).Key
## bootable NIC BootOption device, for use in setting BootOrder (the corresponding VirtualEthernetCard device on the VM has PXE enabled, assumed)
$oBootableNIC = New-Object -TypeName VMware.Vim.VirtualMachineBootOptionsBootableEthernetDevice -Property @{"DeviceKey" = $intNICDeviceKey}

## get the VirtualDisk device, then grab its Key (DeviceKey, used later)
$intHDiskDeviceKey = ($vm.ExtensionData.Config.Hardware.Device | ?{$_.DeviceInfo.Label -eq $strBootHDiskDeviceName}).Key
## bootable Disk BootOption device, for use in setting BootOrder (the corresponding VirtualDisk device is bootable, assumed)
$oBootableHDisk = New-Object -TypeName VMware.Vim.VirtualMachineBootOptionsBootableDiskDevice -Property @{"DeviceKey" = $intHDiskDeviceKey}

## bootable CDROM device (per the docs, the first CDROM with bootable media found is used)
$oBootableCDRom = New-Object -Type VMware.Vim.VirtualMachineBootOptionsBootableCdromDevice

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec -Property @{
   
"BootOptions" = New-Object VMware.Vim.VirtualMachineBootOptions -Property @{
        BootOrder
= $oBootableNIC, $oBootableHDisk, $oBootableCDRom
    }
## end new-object
} ## end new-object

## reconfig the VM to use the spec with the new BootOrder
$vm.ExtensionData.ReconfigVM_Task($spec)

You can, of course, check the VM's current boot order by going to its BIOS settings screen at boot, or by:

## see the VM's current boot order
(Get-VM $strVMName).Extensiondata.Config.BootOptions

Other info:

Enjoy

Updated 06 Jan 2012 by mattboren:  also to note:  something to consider when updating the BootOrder in the  way that I described:  it seems to disable updating the boot order via  the BIOS settings screen.  So, if you require to be able to change boot order settings via the BIOS, this may not be the way to go.

0 Kudos
reebobonk
Enthusiast
Enthusiast

Hi,

If I use this script I get an error:

"You cannot call a method on a null-valued expression."

+ $vm.ExtensionData.ReconfigVM_Task($spec)

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

    + FullyQualifiedErrorId : InvokeMethodOnNull

When I run  (Get-VM $strVMName).Extensiondata.Config.BootOptions

I get this:


BootDelay           : 0
EnterBIOSSetup      : False
BootRetryEnabled    : False
BootRetryDelay      : 10000
BootOrder           :
NetworkBootProtocol :

This are the versions of the modules:

ModuleType Version    Name                                ExportedCommands                                                            

---------- -------    ----                                ----------------                                                            

Binary     6.0.0.0    VMware.VimAutomation.Cis.Core                                                                                   

Binary     6.3.0.0    VMware.VimAutomation.Cloud                                                                                      

Manifest   6.3.0.0    VMware.VimAutomation.Common                                                                                     

Manifest   6.3.0.0    VMware.VimAutomation.Core           HookGetViewAutoCompleter                                                    

Binary     6.0.0.0    VMware.VimAutomation.HA                                                                                         

Binary     1.0.0.0    VMware.VimAutomation.License                                                                                    

Binary     6.0.0.0    VMware.VimAutomation.PCloud                                                                                     

Manifest   6.3.0.0    VMware.VimAutomation.SDK                                                                                        

Binary     6.0.0.0    VMware.VimAutomation.Storage                                                                                    

Binary     6.3.0.0    VMware.VimAutomation.Vds                                                                                        

Binary     6.3.0.0    VMware.VimAutomation.vROps                                                                                      

Binary     6.0.0.0    VMware.VumAutomation                                                                                           

0 Kudos
LucD
Leadership
Leadership

Looks like the $vm variable might be empty.

Did you do

$vm = Get-VM $strVMName

before calling the method?


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

0 Kudos
reebobonk
Enthusiast
Enthusiast

I forgot that but hen I get in vCenter:

pastedImage_0.png

0 Kudos
LucD
Leadership
Leadership

Which vSphere version are you using?

It looks like your PowerCLI version is quite old, perhaps you should consider upgrading.

I just tried with below script in vSphere 6.5 with PowerCLI 11.0.0, and there it works without an issue.

$strVMName = "MyVM"

$strBootNICDeviceName = "Network adapter 1"

$strBootHDiskDeviceName = "Hard disk 1"

$vm = Get-VM $strVMName

$intNICDeviceKey = ($vm.ExtensionData.Config.Hardware.Device | ?{$_.DeviceInfo.Label -eq $strBootNICDeviceName}).Key

$oBootableNIC = New-Object -TypeName VMware.Vim.VirtualMachineBootOptionsBootableEthernetDevice -Property @{"DeviceKey" = $intNICDeviceKey}

$intHDiskDeviceKey = ($vm.ExtensionData.Config.Hardware.Device | ?{$_.DeviceInfo.Label -eq $strBootHDiskDeviceName}).Key

$oBootableHDisk = New-Object -TypeName VMware.Vim.VirtualMachineBootOptionsBootableDiskDevice -Property @{"DeviceKey" = $intHDiskDeviceKey}

$oBootableCDRom = New-Object -Type VMware.Vim.VirtualMachineBootOptionsBootableCdromDevice

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec -Property @{

    "BootOptions" = New-Object VMware.Vim.VirtualMachineBootOptions -Property @{

        BootOrder = $oBootableNIC, $oBootableHDisk, $oBootableCDRom

    }

}

$vm.ExtensionData.ReconfigVM_Task($spec)


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

0 Kudos
reebobonk
Enthusiast
Enthusiast

vSphere 5.5.0

PowerCLI Version

----------------

   VMware vSphere PowerCLI 6.3 Release 1 build 3639347

---------------

Component Versions

---------------

   VMware Cloud Infrastructure Suite PowerCLI Component 6.3 build 3639341

   VMWare AutoDeploy PowerCLI Component 6.0 build 3511413

   VMWare ImageBuilder PowerCLI Component 6.0 build 3511413

   VMware vSphere PowerCLI Component 6.3 build 3639341

   VMware VDS PowerCLI Component 6.3 build 3639341

   VMware vCloud Director PowerCLI Component 6.3 build 3615264

   VMware HA PowerCLI Component 6.0 build 3625284

   VMware License PowerCLI Component 6.0 build 3615733

   VMware vCloud Air PowerCLI Component 6.3 build 3615264

   VMware PowerCLI Component for Storage Management 6.0 build 3617867

   VMware vROps PowerCLI Component 6.3 build 3615304

   VMware vSphere Update Manager PowerCLI 6.1 build 3607502

0 Kudos
reebobonk
Enthusiast
Enthusiast

Ah, I ran your script, instead of the script from mattboren and that worked.

0 Kudos