Home > create_vmware_osx_install_dmg, Mac OS X, Scripting, VMware, VMware ESXi > VMware custom OS X installer script adds support for VMware ESXi

VMware custom OS X installer script adds support for VMware ESXi

I’ve updated the create_vmware_osx_install_dmg.sh script that I had previously posted about here. It now includes the ability to create an .iso file, which can be used with VMware ESXi servers running on Apple hardware. See below the jump for the details.

When running the script, the user will now be asked if they want an ISO disk image for use with VMware ESXi.

Screen Shot 2013-08-09 at 10.11.59 PM

If the user selects Yes, both a .dmg and an .iso file will be created and stored in the output directory.

Screen Shot 2013-08-09 at 10.16.08 PM

Screen Shot 2013-08-09 at 10.17.04 PM

If the user selects No, a “— ISO disk image will not be created. Proceeding..” message will be displayed and a .dmg file will be created and stored in the output directory.

Screen Shot 2013-08-09 at 10.37.34 PM

The virtual drives created by VMware ESXi for OS X VMs are not automatically formatted, so support for System Image Utility‘s AutoPartition.app has been included. AutoPartition.app runs before the installation of OS X to make sure the boot drive is formatted and named correctly for the automated installation.

Screen Shot 2013-08-09 at 10.48.49 PM

Screen Shot 2013-08-09 at 10.59.58 PM

The updated script is below and has also been posted to my GitHub repo. For more details on configuring and running the script, click here.

# Preparation script for a customized OS X installer for use with VWware Fusion
# What the script does, in more detail:
# 1. Mounts the InstallESD.dmg using a shadow file, so the original DMG is left
# unchanged.
# 2. minstallconfig.xml and PartitionInfo.plist are also copied, which is looked for by the installer environment's
# rc.* files that first load with the system. This allows us to never actually modify the
# BaseSystem.dmg and only drop in these extra files.
# 3. Additional installer packages can be added using First Boot Package Install.pkg,
# which is added to the OS X install by way of the OSInstall.collection file. The instructions
# on how to use this package are documented here:
# https://derflounder.wordpress.com/2013/05/13/first-boot-package-install-pkg/
# 4. If desired, a second disk image in .iso format can be generated for use with VMware ESXi
# servers running on Apple hardware. The .iso file will also be stored in the output directory.
# Original script written by Tim Sutton:
# https://github.com/timsutton/osx-vm-templates/tree/master/prepare_iso
# Thanks: (brought over from Tim's original script)
# Idea and much of the implementation thanks to Pepijn Bruienne, who's also provided
# some process notes here: https://gist.github.com/4542016. The sample minstallconfig.xml,
# use of OSInstall.collection and readme documentation provided with Greg Neagle's
# createOSXInstallPkg tool also proved very helpful. (http://code.google.com/p/munki/wiki/InstallingOSX)
# User creation via package install method also credited to Greg, and made easy with Per
# Olofsson's CreateUserPkg (http://magervalp.github.io/CreateUserPkg)
usage() {
cat <<EOF
$(basename "$0") "/path/to/InstallESD.dmg" /path/to/output/directory
$(basename "$0") "/path/to/Install OS X [Mountain] Lion.app" /path/to/output/directory
Converts a 10.7/10.8 installer image to a new image that contains components
used to perform an automated installation. The new image will be named
msg_status() {
echo "\033[0;32m– $1\033[0m"
msg_error() {
echo "\033[0;31m– $1\033[0m"
if [ $# -eq 0 ]; then
exit 1
if [ $(id -u) -ne 0 ]; then
msg_error "This script must be run as root, as it saves a disk image with ownerships enabled."
exit 1
if [ ! -e "$ESD" ]; then
msg_error "Input installer image $ESD could not be found! Exiting.."
exit 1
if [ -d "$ESD" ]; then
# we might be an install .app
if [ -e "$ESD/Contents/SharedSupport/InstallESD.dmg" ]; then
msg_error "Can't locate an InstallESD.dmg in this source location $ESD!"
SCRIPT_DIR="$(cd $(dirname "$0"); pwd)"
if [ "$2" == "" ]; then
msg_error "Currently an explicit output directory is required as the second argument."
exit 1
if [ ! -d "$OUT_DIR" ]; then
msg_status "Destination dir $OUT_DIR doesn't exist, creating.."
mkdir -p "$OUT_DIR"
if [ -e "$ESD.shadow" ]; then
msg_status "Removing old shadow file.."
rm "$ESD.shadow"
# Script will prompt user if they want an additional image in .iso
# format for use with a VMware ESXi server.
echo "Do you also want an ISO disk image for use with VMware ESXi?"
select yn in "Yes" "No"; do
case $yn in
Yes) ISO=1; break;;
No ) msg_error "ISO disk image will not be created. Proceeding.."; break;;
MNT_ESD=$(/usr/bin/mktemp -d /tmp/vmware-osx-esd.XXXX)
SHADOW_FILE=$(/usr/bin/mktemp /tmp/vmware-osx-shadow.XXXX)
msg_status "Attaching input OS X installer image with shadow file.."
hdiutil attach "$ESD" -mountpoint "$MNT_ESD" -shadow "$SHADOW_FILE" -nobrowse -owners on
if [ $? -ne 0 ]; then
[ ! -e "$ESD" ] && msg_error "Could not find $ESD in $(pwd)"
msg_error "Could not mount $ESD on $MNT_ESD"
exit 1
DMG_OS_VERS=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$MNT_ESD/System/Library/CoreServices/SystemVersion.plist")
DMG_OS_VERS_MAJOR=$(echo $DMG_OS_VERS | awk -F "." '{print $2}')
DMG_OS_BUILD=$(/usr/libexec/PlistBuddy -c 'Print :ProductBuildVersion' "$MNT_ESD/System/Library/CoreServices/SystemVersion.plist")
if [ -e "$OUTPUT_DMG" ]; then
msg_error "Output file $OUTPUT_DMG already exists! We're not going to overwrite it, exiting.."
hdiutil detach "$MNT_ESD"
exit 1
create_bom() {
/bin/cat > $SUPPORT_DIR/10_8_AP_bomlist << BOMLIST
./System/Library/CoreServices/System Image Utility.app
./System/Library/CoreServices/System Image Utility.app/Contents
./System/Library/CoreServices/System Image Utility.app/Contents/Library
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Info.plist
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/MacOS
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/MacOS/AutoPartition
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/PkgInfo
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/AutoPartition.icns
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/English.lproj
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/English.lproj/Localizable.strings
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/English.lproj/MainMenu.nib
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/French.lproj
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/French.lproj/Localizable.strings
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/French.lproj/MainMenu.nib
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/German.lproj
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/German.lproj/Localizable.strings
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/German.lproj/MainMenu.nib
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/Japanese.lproj
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/Japanese.lproj/Localizable.strings
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/Resources/Japanese.lproj/MainMenu.nib
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/_CodeSignature
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/_CodeSignature/CodeResources
./System/Library/CoreServices/System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app/Contents/version.plist
partition_info() {
/bin/cat > $SUPPORT_DIR/PartitionInfo.plist << PARTITIONXML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
<plist version="1.0">
<string>Macintosh HD</string>
# We need to copy over the AutoPartition.app from System Image Utility, and it needs to match the version of the Guest OS
# 10.7 systems need to get Server Admin Tools here:
# http://support.apple.com/kb/DL1596
# direct link: http://support.apple.com/downloads/DL1596/en_US/ServerAdminTools.dmg
AUTOPART_APP_IN_SIU="System Image Utility.app/Contents/Library/Automator/Create Image.action/Contents/Resources/AutoPartition.app"
OSX_VERS=$(sw_vers -productVersion | awk -F "." '{print $2}')
if [ $DMG_OS_VERS_MAJOR -eq 8 ]; then
if [ $OSX_VERS -eq 7 ]; then
msg_status "To build Mountain Lion on Lion, we need to extract AutoPartition.app from within the 10.8 installer ESD."
SIU_TMPDIR=$(/usr/bin/mktemp -d /tmp/siu-108.XXXX)
msg_status "Expanding flat package.."
pkgutil –verbose –expand "$MNT_ESD/Packages/Essentials.pkg" "$SIU_TMPDIR/expanded"
msg_status "Generating BOM.."
mkbom -s -i "$SUPPORT_DIR/10_8_AP_bomlist" "$SUPPORT_DIR/BOM"
msg_status "Extracting AutoPartition.app using ditto.."
ditto –bom "$SUPPORT_DIR/BOM" -x "$SIU_TMPDIR/expanded/Payload" "$SIU_TMPDIR/ditto"
if [ ! -d "$SUPPORT_DIR/AutoPartition-10.${DMG_OS_VERS_MAJOR}" ]; then
mkdir "$SUPPORT_DIR/AutoPartition-10.${DMG_OS_VERS_MAJOR}"
msg_status "Copying out AutoPartition.app.."
cp -R "$SIU_TMPDIR/ditto/System/Library/CoreServices/$AUTOPART_APP_IN_SIU" "$SUPPORT_DIR/AutoPartition-10.${DMG_OS_VERS_MAJOR}/"
msg_status "Removing temporary extracted files.."
rm -rf "$SIU_TMPDIR"
elif [ $OSX_VERS -eq 8 ]; then
if [ ! -e "$AUTOPART_TOOL" ]; then
msg_error "We're on Mountain Lion, and should have System Image Utility available at $AUTOPART_TOOL, but it's not available for some reason."
exit 1
# on Lion, we first check if Server Admin Tools are already installed..
elif [ $DMG_OS_VERS_MAJOR -eq 7 ]; then
msg_status "Building OS X 10.${DMG_OS_VERS_MAJOR}, so trying to locate System Image Utility from Server Admin Tools.."
# TODO: Sanity-check that this is actually the right version of SIU
if [ ! -d "$AUTOPART_TOOL" ]; then
# then we check if _we_ installed them in support/AutoPartition-10.7
if [ ! -d "$AUTOPART_TOOL" ]; then
# Lion SAT download
msg_status "It doesn't seem to be installed."
msg_status "Attempting download of the Server Admin Tools.."
SAT_TMPDIR=$(/usr/bin/mktemp -d /tmp/server-admin-tools.XXXX)
curl -L "$SAT_URL" -o "$SAT_TMPDIR/sat.dmg"
if [ ! -f "$SAT_TMPDIR/sat.dmg" ]; then
msg_error "Server Admin Tools failed to download. Stopping build process."
exit 1
msg_status "Attaching Server Admin Tools.."
hdiutil attach "$SAT_TMPDIR/sat.dmg" -mountpoint "$SAT_TMPDIR/mnt"
msg_status "Expanding package.."
pkgutil –expand "$SAT_TMPDIR/mnt/ServerAdminTools.pkg" "$SAT_TMPDIR/expanded"
hdiutil detach "$SAT_TMPDIR/mnt"
mkdir "$SAT_TMPDIR/cpio-extract"
msg_status "Extracting payload.."
tar -xz -C "$SAT_TMPDIR/cpio-extract" -f "$SAT_TMPDIR/expanded/ServerAdminTools.pkg/Payload"
if [ ! -d "$SUPPORT_DIR/AutoPartition-10.${DMG_OS_VERS_MAJOR}" ]; then
mkdir "$SUPPORT_DIR/AutoPartition-10.${DMG_OS_VERS_MAJOR}"
msg_status "Copying out AutoPartition.app"
cp -R "$SAT_TMPDIR/cpio-extract/Applications/Server/$AUTOPART_APP_IN_SIU" "$SUPPORT_DIR/AutoPartition-10.${DMG_OS_VERS_MAJOR}/"
rm -rf "$SAT_TMPDIR"
# AUTOPART_TOOL="$SUPPORT_DIR/AutoPartition-${DMG_OS_VERS_MAJOR}/AutoPartition.app"
else msg_status "Found AutoPartition.app at $AUTOPART_TOOL.."
elif [ $DMG_OS_VERS_MAJOR -lt 7 ]; then
msg_error "This script does not support support building disk images for OS X versions prior to 10.7."
exit 1
# Add First Boot Package Install.pkg to the OS X installer
FIRSTBOOT_PKG="$SUPPORT_DIR/First Boot Package Install.pkg"
# Writing PartitionInfo.plist to the support directory
# Add our auto-setup files: minstallconfig.xml and OSInstall.collection
msg_status "Adding automated components.."
mkdir "$MNT_ESD/Packages/Extras"
cp "$SUPPORT_DIR/minstallconfig.xml" "$MNT_ESD/Packages/Extras/"
cp "$SUPPORT_DIR/OSInstall.collection" "$MNT_ESD/Packages/"
cp "$SUPPORT_DIR/PartitionInfo.plist" "$MNT_ESD/Packages/Extras/"
cp -R "$AUTOPART_TOOL" "$MNT_ESD/Packages/Extras/AutoPartition.app"
cp -r "$FIRSTBOOT_PKG" "$MNT_ESD/Packages/"
rm -rf "$SUPPORT_DIR/tmp"
msg_status "Unmounting.."
hdiutil detach "$MNT_ESD"
msg_status "Converting to .dmg disk image.."
/usr/bin/hdiutil convert -format UDZO -o "$OUTPUT_DMG" -shadow "$SHADOW_FILE" "$ESD"
if [[ $ISO = 1 ]]; then
msg_status "Converting to .iso disk image…."
/usr/bin/hdiutil convert "$OUTPUT_DMG" -format UDTO -o "$OUTPUT_ISO"
/bin/mv $OUT_DIR/OSX_InstallESD_${DMG_OS_VERS}_${DMG_OS_BUILD}.iso.cdr "$OUTPUT_ISO"
rm -rf "$MNT_ESD"
rm -rf "$SUPPORT_DIR/"AutoPartition-*
rm "$SUPPORT_DIR/PartitionInfo.plist"
if [ -f "$SUPPORT_DIR/10_8_AP_bomlist" ]; then
rm "$SUPPORT_DIR/10_8_AP_bomlist"
if [ -n "$SUDO_UID" ] && [ -n "$SUDO_GID" ]; then
msg_status "Fixing permissions.."
msg_status "Checksumming .dmg disk image.."
MD5=$(md5 -q "$OUTPUT_DMG")
msg_status "MD5: $MD5"
msg_status "Built .dmg disk image is located at $OUTPUT_DMG."
if [ -f "$OUTPUT_ISO" ]; then
msg_status "Checksumming .iso disk image.."
MD5=$(md5 -q "$OUTPUT_ISO")
msg_status "MD5: $MD5"
msg_status "Built .iso disk image is located at $OUTPUT_ISO."
msg_status "Build process finished."

view raw


hosted with ❤ by GitHub

  1. .
    June 23, 2014 at 10:24 am

    Great script. Just wondering if you know where I can find some documentation regarding the Autopartition.app? I was hoping to use your script to provide end users at remote locations a bootable USB flash drive containing your created image but have it perform some custom partitioning.

    I can see the plist, just trying to figure out whats the best way to implement it.

    We partition our HD’s with two partitions SYSTEM and DATA and my post image script binds the system to AD and redirects local /Users to DATA volume.

    I was hoping to use your script for both Macs that have just been purchased (HD is Macintosh HD, so AutoPartition would do its magic) and older systems requiring a re-image (already partitioned) so AutoPartition would not do anything, and installer would just erase and install the SYSTEM partition.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: