Skip to content

Instantly share code, notes, and snippets.

@jvarn
Last active July 4, 2023 05:28
Show Gist options
  • Save jvarn/dff123cea56bfd6875095c051ac19593 to your computer and use it in GitHub Desktop.
Save jvarn/dff123cea56bfd6875095c051ac19593 to your computer and use it in GitHub Desktop.
Make Windows USB Installer on Mac
#!/bin/bash
# Installs Homebrew and Wimlib if not already installed,
# then formats and prepares an external USB device as
# a bootable Windows installer from your Windows ISO.
#
# Usage: ./make_windows_usb.sh windows_installer.iso
# (first make executable with: chmod u+x ./make_windows_usb.sh)
#
# Insert single external USB target device before running.
# Do not use blindly – bad things can happen.
#######################################################################################
# Colours
# Are there conventions for colour use in bash?
BoldRed='\033[1;31m'
BoldBlue='\033[1;34m'
BoldYellow='\033[1;33m'
BoldGreen='\033[1;32m'
NoColour='\033[0m'
#######################################################################################
# Errors
errors[0]="${BoldRed}No ISO image specified.${NoColour}\nUsage: ./make_windows_usb.sh windows_installer.iso"
errors[1]="${BoldRed}Please make sure you have exactly one USB storage device attached.${NoColour}\nusb_disk_count devices found"
errors[2]="${BoldRed}Fatal Error ${NoColour}There was a problem formatting the disk."
errors[3]="${BoldRed}Fatal Error ${NoColour}There was a problem rsyncing the files."
errors[4]="${BoldRed}Fatal Error ${NoColour}There was a problem creating the installation files."
errors[5]="${BoldRed}Error ${NoColour}There was a problem ejecting the USB device."
errors[6]="${BoldRed}Error ${NoColour}There was a problem unmounting the ISO."
#######################################################################################
# Sanity
# Makes sure a paremeter (ISO file) was specified and only one external USB drive is present
## Paremeter specified? (doesn't check if it actually exists)
if [ $# -eq 0 ]; then
echo -e ${errors[0]}
exit 1
fi
## One external usb drive?
usb_disk_count=$(diskutil list | grep "external" | awk 'END {print NR}')
if [ ! $usb_disk_count -eq 1 ]; then
echo -e ${errors[1]} | sed "s/usb_disk_count/$usb_disk_count/g"
exit 1
fi
#######################################################################################
# Homebrew
# Installs Homebrew and checks for updates if already installed
echo -e "${BoldBlue}Preparing Homebrew.${NC}"
which -s brew
if [[ $? != 0 ]] ; then
echo -e "${BoldGreen}Installing Homebrew.${NoColour}"
echo "Installing Homebrew."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
else
echo -e "${BoldGreen}Making sure Homebrew is up-to-date.${NC}"
brew update &>/dev/null
fi
#######################################################################################
# Wimlib
# Installs Wimlib and checks for updates if already installed
echo -e "${BoldBlue}Preparing Wimlib.${NC}"
lib="wimlib"
lib_exec="wimlib-imagex"
which -s $lib_exec
if [[ $? != 0 ]] ; then
echo -e "${BoldGreen}Installing Wimlib.${NC}"
brew install $lib
else
echo -e "${BoldGreen}Making sure Wimlib is up-to-date.${NC}"
brew outdated $lib &>/dev/null || brew install $lib
fi
#######################################################################################
# ISO disc image
# Mounts the ISO file and gets its device and mountpoint
echo -e "${BoldBlue}Preparing ISO.${NC}"
image_file="$1"
IFS=$'\n' read -d'\n' iso_dev_entry iso_mount_point < <(
hdiutil mount "${image_file}" | awk '{print $1; print $2}'
)
#######################################################################################
# USB Drive file copy
# Writes to first "external" USB drive (unplug any others!)
echo -e "${BoldBlue}Preparing USB.${NC}"
usb_disk=$(diskutil list | grep "external" | head -n 1 | awk '{print $1}')
usb_label="WINDOWS"
usb_mount_point="/Volumes/$usb_label"
echo -e "${BoldYellow}Ready to format $usb_disk.${NoColour}"
read -p "Press any key to continue or ctrl-c to abort."
## Format
diskutil eraseDisk MS-DOS "${usb_label}" MBR ${usb_disk} || echo -e ${errors[2]}; exit 1
## Rsync
echo -e "${BoldYellow}Ready to start writing contents of $image_file to $usb_disk.${NoColour}"
read -p "Press any key to copy source files to USB (step 1)."
rsync -avh --progress --exclude=sources/install.wim ${iso_mount_point}/ ${usb_mount_point} || echo -e errors[3]; exit 1
## Wimlib
read -p "Press any key to copy files to USB (step 2)."
wimlib-imagex split "$iso_mount_point/sources/install.wim" "$usb_mount_point/sources/install.swm" 3800 || echo -e errors[4]; exit 1
echo -e "${BoldBlue}All done.${NoColour}"
read -p "Press any key to eject mounted volumes or ctrl-c to abort."
hdiutil eject ${usb_mount_point} || echo -e errors[5]
hdiutil eject ${iso_mount_point} || echo -e errors[6]
echo -e "${BoldGreen}All done!${NoColour}"
echo "You can unplug the usb drive now."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment