Script to migrate VMWare ESXi Virtual machine to Proxmox VE 7.1
Introduction
Migrating virtual machines between platforms can be a pain in the ass to put it mildly.
I have recently decided to migrate from ESXi to Proxmox VE, simply because it allows me downscale my lab from several “BIG” machines into a single machine.
When converting a lot of VM’s from ESXi to Proxmox VE I basically had to write the same commands over and over in the same sequence.
So I decided to create a little wrapper script that can do the bare minimum but might also be useful for others.
Prerequisites
Software is required to allow the migration to happen, but not a lot.
Ovftool is what makes the magic work. It can convert a virtual machine into a ovf package.
Head to vmware’s website and download version 4.4.3 of ovftool.
Copy the downloaded zip VMware-ovftool-4.4.3-18663434-lin.x86_64.zip
to your proxmox VE server.
Unzip the archive via the command unzip
. If you get a command not found
error message simply install unzip via apt-get install unzip
Then you unzip the archive via the command unzip VMware-ovftool-4.4.3-18663434-lin.x86_64.zip
This should create a folder in the current directory called ovftool
.
Script
#!/bin/bash
EXE=/tank/tools/ovftool/ovftool
RED='\033[0;31m'
NC='\033[0m' # No Color
TYPE=""
TEMP="/tmp"
HOSTNAME=""
USERNAME="root"
VMNAME=""
DESTINATION=""
VMX=""
VMID=""
CONFIRM=""
CLEAN=""
LOG=""
CheckArguments()
{
while [[ $# -gt 0 ]]; do
case $1 in
--online)
TYPE="ONLINE"
shift
;;
--offline)
TYPE="OFFLINE"
shift # past argument
;;
--temp)
TEMP="$2"
shift # past argument
shift # past value
;;
--vmx)
VMX="$2"
shift # past argument
shift # past value
;;
--hostname)
HOSTNAME="$2"
shift # past argument
shift # past value
;;
--vmid)
VMID="$2"
shift # past argument
shift # past value
;;
--username)
USERNAME="$2"
shift # past argument
shift # past value
;;
--destination)
DESTINATION="$2"
shift # past argument
shift # past value
;;
--yes)
CONFIRM="YES"
shift # past argument
;;
--log)
LOG="$2"
shift # past argument
shift
;;
--clean)
CLEAN="YES"
shift # past argument
;;
--*)
echo "Unknown option $1"
exit 1
;;
esac
done
}
Write()
{
echo -e "$1"
}
Usage()
{
echo -e "${NC}"
cat << EOT
ESXi -> Proxmox helper script
Simplifies import/export into a single command
Usage: $1 <arguments>
Arguments:
--online : For direct online import from ESXi
--offline : For import of vmdk from filesystem
--temp <path> : Where to store temporary files before
import into proxmox - defaults to /tmp if not provided
--vmx <vmx> : Full path to vmx file
--hostname <hostname> : hostname for esxi server
--username <username> : username for esxi - defaults to root if not provided
--vmname <vmname> : Name of VM as its presented in ESXi
- if name contains spaces enclose it in quotes
--destination <storage id> : ID of destination storage inside proxmox
--vmid <vmid> : Destination ID of vm when its imported. Must be unique
--yes : Assume yes to all questions
--log <path> : Full path to log file - if none is provided, no logging is done
--clean : Delete ovf file after import into proxmox
Examples:
$0 --offline --temp /tmp --vmx '/mnt/data/esxi/my\ vm/my\ vm.vmx' --destination vms --vmid 300
$0 --online --temp /tmp --hostname vms.root.dom --username john --vmname 'my vm' --destination vms --vmid 300
EOT
}
if [ ! -f $EXE ]
then
Write "$EXE does not exist"
exit 2
fi
if [ "$#" -eq "0" ]
then
Write "${RED}Missing arguments"
Usage $0
exit 1
fi
CheckArguments [email protected]
MISSINGARGS=""
if [ "$TYPE" == "" ]
then
MISSINGARGS="\n--offline or --online"
fi
if [ "$DESTINATION" == "" ]
then
MISSINGARGS+="\n--destination"
fi
if [ "$VMID" == "" ]
then
MISSINGARGS+="\n--vmid"
fi
if [ "$MISSINGARGS" != "" ]
then
Write "Missing required arguments:"
Write "$MISSINGARGS"
exit 3
fi
if [ "$TYPE" == "OFFLINE" ]
then
Write ""
Write "Ready to import"
Write "-------------------------------------------------------------"
Write "Temporary storage : '$TEMP'"
Write "VM Storage : '$DESTINATION'"
Write "VMX Path : '$VMX'"
Write "Destination VM ID : '$VMID'"
Write "-------------------------------------------------------------"
VMXFILE=$(basename $VMX)
VMNAME=$(basename -s .vmx $VMX)
# echo "Source vmx:$VMXFILE"
# echo "Source name:$VMNAME"
if [ "$CONFIRM" == "" ]
then
Write ""
read -p "Export vm to ovf format? (y/n)" -n 1 -r REPLY
Write ""
if [ "$REPLY" != "y" -a "$REPLY" != "Y" ]
then
exit 10
fi
fi
Write "Exporting $VMNAME to $TEMP"
Write "Eecuting '$EXE $VMX $TEMP'"
ARGS=""
if [ "$LOG" != "" ]
then
ARGS="--X:logLevel=verbose --X:logFile=$LOG"
fi
$EXE $ARGS --noNvramFile --lax $VMX $TEMP
Write ""
Write "Export complete"
Write "OVF file should be located in folder $TEMP/$VMNAME/"
Write ""
if [ "$CONFIRM" == "" ]
then
Write "VM $VMID is ready to be imported from ($TEMP/$VMNAME/$VMNAME.ovf)"
Write ""
read -p "Import VM $VMID to proxmox? (y/n)" -n 1 -r REPLY
Write ""
if [ "$REPLY" != "y" -a "$REPLY" != "Y" ]
then
exit 10
fi
fi
Write "Importing VM '$VMID' ($TEMP/$VMNAME/$VMNAME.ovf) to storage '$DESTINATION'"
Write ""
qm importovf $VMID $TEMP/$VMNAME/$VMNAME.ovf $DESTINATION
if [ "$CLEAN" == "YES" ]
then
rm -rf $TEMP/$VMNAME
fi
fi
exit 0
Usage
The script has to be located on your PVE server - and the script needs to be modified with a correct path to where you unzipped the ovftool.
When that is done you can simply call the script like this:
./import_esxi.sh --offline --temp /tmp --vmx '/mnt/data/esxi/my\ vm/my\ vm.vmx' --destination vms --vmid 300
./import_esxi.sh --online --temp /tmp --hostname vms.root.dom --username john --vmname 'my vm' --destination vms --vmid 300
Where the first example is if you have already shut down your ESXi server and have access to the datastore - and the second example is when you have the ESXi still running.
The script then either corrects directly to the ESXi server and exports a ovf - or coverts the vmx/vmdk directly to a ovf.
When the export has been done the script will ask whether or not to import the exported vm into proxmox.
Simple.
If you like the script please let me know in the comments below.