Skip to main content

Automatic Virtual Machine Creation from command line in VMware's ESXi

4 min read

Older Article

This article was published 13 years ago. Some information may be outdated or no longer applicable.

I work with Virtual Machines daily, mostly VMWare’s ESXi, a bare metal embedded hypervisor. (A hypervisor is just a piece of software that creates and runs virtual machines.) Virtualisation is brilliant. A server you can crash and restore from a snapshot? That gives developers and sysadmins genuine flexibility to build new things and test updates without fear.

I look after about 30 virtual machines. The worst part was the initial setup: spinning up 10+ VMs a day, each requiring the vSphere client, configuring RAM, HDD, CPU, bolting on an ISO image, powering it up. Then the next one. And the next.

So I wrote a script that automates the lot. Copy it onto the ESXi via scp, pass in the right parameters, hit enter. The VM spins up in about five seconds.

The bash script is available on Github. The first thing to note is that the first line isn’t /bin/bash but:

#!/bin/sh

ESXi runs a stripped back version of Linux with ‘BusyBox’, a single binary that provides a handful of basic commands. Because of these limitations, /bin/bash doesn’t exist.

My script accepts the following parameters:

- n: Name of the Virtual Machine (this parameter is required)
- c: Number of virtual CPUs (has to be an integer and between 1 and 32
- i: Location of an ISO image (has to have an .iso extension)
- r: RAM size in MB (needs to be integer and greater than 1MB)
- s: Disk size in GB (needs to be an integer and greater than 1GB)

The only required parameter is the machine name. Everything else is optional, and other than the ISO location, all parameters have defaults: CPU: 2, RAM: 4096MB, HDD-SIZE: 20GB.

Here’s the main while loop that handles the heavy lifting:

while getopts n:c:i:r:s: option
do
    case $option in
      n)
    NAME=${OPTARG};
    FLAG=false;
    if [ -z $NAME ]; then
      ERR=true
      MSG="$MSG | Please make sure to enter a VM name."
    fi
    ;;
      c)
    CPU=${OPTARG}
    if [ `echo "$CPU" | egrep "^-?[0-9]+$"` ]; then
      if [ "$CPU" -le "0" ] || [ "$CPU" -ge "32" ]; then
      ERR=true
        MSG="$MSG | The number of cores has to be between 1 and 32."
      fi
    else
      ERR=true
      MSG="$MSG | The CPU core number has to be an integer."
    fi
    ;;
      i)
    ISO=${OPTARG}
    if [ ! `echo "$ISO" | egrep "^.*\.(iso)$"` ]; then
      ERR=true
      MSG="$MSG | The extension should be .iso"
    fi
    ;;
      r)
    RAM=${OPTARG}
    if [ `echo "$RAM" | egrep "^-?[0-9]+$"` ]; then
      if [ "$RAM" -le "0" ]; then
        ERR=true
        MSG="$MSG | Please assign more than 1MB memory to the VM."
      fi
    else
      ERR=true
      MSG="$MSG | The RAM size has to be an integer."
    fi
    ;;
      s)
    SIZE=${OPTARG}
    if [ `echo "$SIZE" | egrep "^-?[0-9]+$"` ]; then
      if [ "$SIZE" -le "0" ]; then
        ERR=true
        MSG="$MSG | Please assign more than 1GB for the HDD size."
      fi
    else
      ERR=true
      MSG="$MSG | The HDD size has to be an integer."
    fi
    ;;
      \?) echo "Unknown option: -$OPTARG" >&2; phelp; exit 1;;
      :) echo "Missing option argument for -$OPTARG" >&2; phelp; exit 1;;
      *) echo "Unimplimented option: -$OPTARG" >&2; phelp; exit 1;;
    esac
done

These values create the VM folder, wire up the configuration files, register the machine with ESXi, and fire it up:

mkdir ${NAME}

#Creating the actual Virtual Disk file (the HDD) with vmkfstools
vmkfstools -c "${SIZE}"G -a lsilogic $NAME/$NAME.vmdk

#Creating the config file
touch $NAME/$NAME.vmx

#writing information into the configuration file
cat << EOF > $NAME/$NAME.vmx
#adding variables -- note code has been trimmed:
numvcpus = "${CPU}"
scsi0.present = "TRUE"
scsi0.sharedBus = "none"
scsi0.virtualDev = "lsilogic"
memsize = "${RAM}"

EOF

#Adding Virtual Machine to VM register - modify your path accordingly!!
MYVM=`vim-cmd solo/registervm /vmfs/volumes/datastore1/${NAME}/${NAME}.vmx`
#Powering up virtual machine:
vim-cmd vmsvc/power.on $MYVM

Done. A running virtual machine. Grab the full source code on Github.

For more .vmx configuration options, have a look at this site.