Skip to content

Instantly share code, notes, and snippets.

@mpepping
Created October 23, 2022 11:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mpepping/0335de491d3da31aae695752e3cd800f to your computer and use it in GitHub Desktop.
Save mpepping/0335de491d3da31aae695752e3cd800f to your computer and use it in GitHub Desktop.
ESXi clone VM shell-script
#!/bin/sh
#File: clonevm.sh
#Version: 2020.09.23.A
#Author: www.grangerx.com
#Set debug = true to enable debug echoes.
debug=false
#For format: accepts same, zeroedthick, eagerzeroedthick, thin, rdm:dev, rdmp:dev, or 2gbsparse.
format="thin"
#---------------------
#-v- debugecho()
#---------------------
debugecho() {
if [ $debug == "true" ]
then
echo "$*"
fi
}
#---------------------
#-^- debugecho()
#---------------------
#Generate a format parameter based on selected format:
formatparam=""
if [ "${format}" != "same" ]; then
formatparam="-d ${format}"
fi
debugecho "FORMAT for VMDKs: ${formatparam}"
#01. validate that source vm name was given as parameter #1
srcvm="${1}"
#02. validate that dest vm name was given as parameter #2
dstvm="${2}"
debugecho "Usage: $0 <name of source VM> <name of dest VM>"
if [ $# -ne 2 ]; then
echo "Usage: $0 <name of source VM> <name of dest VM>"
exit 1
fi
#03. find the source datastore path based on source vm name
#attempt to determine datastore path:
#eval ds_first=$(find /vmfs/volumes/ -mindepth 1 -maxdepth 1 -type l | head -n 1)
#04. get the dirname for the source datastore
eval ds_src=$(dirname $(find /vmfs/volumes/ -type d -name "${srcvm}" ))
debugecho "SRC: ${srcvm}"
debugecho "DST: ${dstvm}"
debugecho "DATASTORE SRC: ${ds_src}"
#05. compute the source folder by concatenating source datastore and source vm name
#get the Source VM dir specification:
srcdirspec="${ds_src}/${srcvm}"
#get the Dest VM dir specification:
dstdirspec="${ds_src}/${dstvm}"
#06. locate the source vmx file in the source folder
#determine the source VMX file:
srcvmx=$( find ${srcdirspec} -mindepth 1 -maxdepth 1 -type f -name \*.vmx | head -n 1 )
debugecho "SRC VMX: ${srcvmx}"
#compute the dest VMX file:
dstvmxspec="${dstdirspec}/${dstvm}.vmx"
debugecho "DST VMX Name: ${dstvmxspec}"
#07. locate the source vmdks within the source vmx file
#determine the source VMDK file:
srcvmdk=$( grep -i vmdk ${srcvmx} | sed -e "s/.*=//g" | sed -e "s/\"//g" )
debugecho "SRC VMDK: ${srcvmdk}"
if [ -d "${srcdirspec}" ]; then
debugecho "Source Path: [${srcdirspec}] does appear to exist."
else
echo "Error: The Source Path: [${srcdirspec}] does not appear to exist."
exit 1
fi
#08. validate that destination folder does not yet exist. Exit if it does.
if [ -d "${dstdirspec}" ]; then
echo "Error: The Dest Path: [${dstdirspec}] appears to already exist."
exit 1
else
#09. create the destination folder
debugecho "Dest Path: [${dstdirspec}] does not appear to already exist."
echo "Creating Dest Path: ${dstdirspec}"
mkdir -p "${dstdirspec}"
if [ ! -d "${dstdirspec}" ]; then
echo "Error: The Dest Path: [${dstdirspec}] did not appear to be created successfully."
exit 1
fi
fi
#10. copy the source vmx file to the destination folder, modifying vm/vmdk names to match dest vm
debugecho "copy SRC VMX to DST VMX and modify contents to use DST naming:"
sed -e "s/${srcvm}/${dstvm}/g" "${srcvmx}" > ${dstvmxspec}
#determine the VMDKs needed to be copied
#11. iterate all source vmdks, copy to dest directory
for thisvmdk in ${srcvmdk}
do
thissrcvmdkfullspec="${srcdirspec}/${thisvmdk}"
thisdstvmdk=$(echo ${thisvmdk} | sed -e "s/${srcvm}/${dstvm}/g")
thisdstvmdkfullspec="${dstdirspec}/${thisdstvmdk}"
debugecho "SRC VMDK name to process: ${thisvmdk}"
debugecho "SRC VMDK fullspec: ${thissrcvmdkfullspec}"
debugecho "DST VMDK name: ${thisdstvmdk}"
debugecho "DST VMDK fullspec: ${thisdstvmdkfullspec}"
echo "/bin/vmkfstools -i ${thissrcvmdkfullspec} ${formatparam} ${thisdstvmdkfullspec}"
/bin/vmkfstools -i "${thissrcvmdkfullspec}" ${formatparam} "${thisdstvmdkfullspec}"
done
#12. Print command required to register VM:
echo "To register the newly cloned VM, execute:"
echo "vim-cmd /solo/register ${dstvmxspec}"
@mpepping
Copy link
Author

mpepping commented Oct 23, 2022

Copied from grangerx.com and saved as gist for reference.

Run from an SSH enabled ESXi shell. Usage: sh clone-vm.sh <name of source VM> <name of dest VM>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment