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

Source: https://tpiros.dev/blog/automatic-virtual-machine-creation-from-command-line-in-vmwares-esxi

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](https://github.com/tpiros/auto-create). The first thing to note is that the first line isn't /bin/bash but:

```bash
#!/bin/sh
```

ESXi runs a stripped back version of Linux with '[BusyBox](http://en.wikipedia.org/wiki/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:

```bash
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:

```bash
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](https://github.com/tpiros/auto-create).

For more .vmx configuration options, have a look [at this site](http://sanbarrow.com/vmx.html).
