How To Change a Xenserver VM Type

Here is a quick and dirty script to change the VM type of an existing Xenserver VM. This can be useful if you are, let’s say, using Linux-based cloning software to clone a Windows VM and you want it to run as fast as possible. You may realize that the system runs very slow. That’s because the Windows VM handles paravirtualization differently than the Linux environment will. You have to change the device type, and this script will help. I added a layer of abstraction to simplify the whole process of switching VM types.

Here are examples of how to run the script:
./change-type myvm This will print out the current VM type as either “windows” or “linux”. A numerical ID is printed in [] that designates the current device_id, for your information.
change-type myvm linux This will change the device type from whatever it is now, to linux.
change-type myvm windows This will change the device type from whatever it is now, to windows.
change-type 00000000-0000-0000-0000-000000000000 linux This will change the device type for the machine with the UUID specified.

#!/bin/bash
# /usr/bin/change-type
#
# Written by Pete Lombardo
#
# This script can change the type of hardware for a VM in a Xen Pool(for example, from Linux to Windows or visa versa).
# It can also be used to resolve a blue screen issue after upgrading the tools inside a Windows VM.
#

if [ ! "$1" == "" ]; then
        uuidtest=`echo $1 | sed -e 's/\-//g' | egrep "[0-9a-f]{32}" | wc -l`
        if [ $uuidtest -eq 0 ]; then
                uuid=`xe vm-list | grep -i ": $1" -B1 | grep uuid | cut -d':' -f2 | cut -d' ' -f2`
                name="$1"
        else
                uuid=$1
                name=`xe vm-list | grep "$uuid" -A1 | grep name | cut -d':' -f2 | cut -d' ' -f2-`
        fi
fi

if [ "$1" == "" ]; then
        echo
        echo "Usage: change-type [machine-name] [type]"
        echo "Available Types: linux,windows"
        echo
        exit
elif [ "$2" == "" ]; then
        echo
        echo "Checking the device type for $name"
        if [ "$uuid" == "" ]; then
                echo
                echo "ERROR: System $1 not found."
                echo
                exit
        fi
        type=`xe vm-param-get uuid=$uuid param-name=platform param-key=device_id 2>/dev/null`
        case $type in
                0001)
                        echo "linux [$type]"
                        ;;
                0002)
                        echo "windows [$type]"
                        ;;
                *)
                        echo "linux [$type]"
                        ;;
        esac
        echo
        exit
fi

case $2 in
linux)
        device="0001"
        ;;
windows)
        device="0002"
        ;;
esac

if [ "$uuid" == "" ]; then
        echo
        echo "ERROR: System $1 not found."
        echo
        exit
fi

xe vm-param-set uuid=$uuid platform:device_id=$device

echo
type=`xe vm-param-get uuid=$uuid param-name=platform param-key=device_id`
        case $type in
                0001)
                        echo "linux [$type]"
                        ;;
                0002)
                        echo "windows [$type]"
                        ;;
                *)
                        echo "linux [$type]"
                        ;;
        esac
echo