Created
April 17, 2022 09:23
-
-
Save jpluimers/92e183f861952540defcf1198828a77b to your computer and use it in GitHub Desktop.
VMware ESXi – Script to clone a VM without vSphere or vCenter. Original: https://grangerx.wordpress.com/2020/09/23/vmware-esxi-script-to-clone-a-vm/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment