Wednesday, September 23, 2020

Modifying Citrix Hypervisor (Xenserver) Guest VM boot order from Command Line

 I recently had need to modify the bios boot order on a bunch of Citrix VMs. This required a dozen or so clicks through the Xencenter interface and I had 100+ machines to do it one. Not wanting to spend all day on it, I decided to script it. However I found only minimal information how to modify the boot settings on VMs through the command line. Here's what I found. 

Note: This is probably only valid for Bios boot type. If your VM is using the UEFI boot mode these instructions may not be valid, proceed with caution. 

 Checking Current Boot Settings

To see your VM's current boot setting, you'll need to find the VM's UUID, then use the vm-param-list command; I then use grep to find what I'm looking for, because the vm-param-list output is copious.

# xe vm-list name-label=myvm #case sensitive name

uuid ( RO) : 12345678-1234-1234-1234-123456789abc
name-label ( RW): myvm
power-state ( RO): running

# xe vm-param-list uuid=12345678-1234-1234-1234-123456789abc | grep HVM-boot
HVM-boot-policy ( RW): BIOS order
HVM-boot-params (MRW): firmware: bios; order: cdn

From this output we see the VM is currently set to BIOS boot (again, I haven't tested this with UEFI) and the order is "cdn". 

The boot order is defined as follows

  • c: HDD
  • d: DVD
  • n: Network 

So a boot order of 'cdn' is first hdd, then dvd, then network. where an order of 'nc' would be first network, then harddrive and no DVD option.

Modifying Boot Seetings

xe has a few different ways to modfy vm params, however I found only one way actually works for the HVM-boot-params. The 'xe vm-param-set' command I found does not work at all, causing duplicate entries which are ignored by the system. 

Instead we have to clear the param first, the use the add command to fill in the new settings.

# xe vm-param-clear uuid=12345678-1234-1234-1234-123456789abc param-name=HVM-boot-params
# xe vm-param-add uuid=12345678-1234-1234-1234-123456789abc param-name=HVM-boot-params order=c firmware=bios 


# xe vm-param-list uuid=12345678-1234-1234-1234-123456789abc | grep HVM-boot
HVM-boot-policy ( RW): BIOS order
HVM-boot-params (MRW): firmware: bios; order: c

Here I have set the only boot option to be the HDD, with no network or DVD boot. 

Scripting it all Together

As I mentioned at the top, I had a whole bunch of machines I needed to remove network and DVD boot from, so I wrote a quick bash script to handle it. This script takes a list of VM names (via a file 'names.txt') and looks up the uuid (via a grep that pulls only the uuid pattern) and automatically sends that to the clear/add commands.

#!/bin/bash

#Expected format of names.txt is one name per line. Remember names are case sensitive.
for line in `cat names.txt`; do
vmuuid=`xe vm-list name-label=$line params=uuid | grep -o -m1 '[0-9a-f]\{8\}-\([0-9a-f]\{4\}-\)\{3\}[0-9a-f]\{12\}'`
echo "$line , $vmuuid"
xe vm-param-clear uuid=$vmuuid param-name=HVM-boot-params
xe vm-param-add uuid=$vmuuid param-name=HVM-boot-params order=c firmware=bios
done;
Hope this helps.