Last active
August 22, 2024 07:57
-
-
Save jvarn/dff123cea56bfd6875095c051ac19593 to your computer and use it in GitHub Desktop.
Make Windows USB Installer on Mac
This file contains 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/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 a single external USB target device before running. | |
# Do not use blindly – bad things can happen. | |
####################################################################################### | |
# Colours | |
BoldRed='\033[1;31m' # Critical Errors | |
BoldGreen='\033[1;32m' # Success Messages | |
BoldYellow='\033[1;33m' # Warnings or User Prompts | |
BoldBlue='\033[1;34m' # Information or Status Messages | |
NoColour='\033[0m' # Reset Colour | |
####################################################################################### | |
# Errors | |
# Using an array to store error messages | |
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 Check | |
if [ $# -eq 0 ]; then | |
echo -e ${errors[0]} | |
exit 1 | |
fi | |
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 | |
echo -e "${BoldBlue}Preparing Homebrew.${NoColour}" | |
which -s brew | |
if [[ $? != 0 ]] ; then | |
echo -e "${BoldYellow}Installing Homebrew.${NoColour}" | |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" | |
else | |
echo -e "${BoldBlue}Making sure Homebrew is up-to-date.${NoColour}" | |
brew update &>/dev/null | |
fi | |
####################################################################################### | |
# Wimlib | |
echo -e "${BoldBlue}Preparing Wimlib.${NoColour}" | |
lib="wimlib" | |
lib_exec="wimlib-imagex" | |
which -s $lib_exec | |
if [[ $? != 0 ]] ; then | |
echo -e "${BoldYellow}Installing Wimlib.${NoColour}" | |
brew install $lib | |
else | |
echo -e "${BoldBlue}Making sure Wimlib is up-to-date.${NoColour}" | |
brew outdated $lib &>/dev/null || brew install $lib | |
fi | |
####################################################################################### | |
# ISO Disc Image | |
echo -e "${BoldBlue}Preparing ISO.${NoColour}" | |
image_file="$1" | |
IFS=$'\n' read -d'\n' iso_dev_entry iso_mount_point < <( | |
hdiutil mount "${image_file}" | awk '{print $1; print $2}' | |
) | |
echo -e "${BoldBlue}ISO mounted at ${iso_mount_point}.${NoColour}" | |
####################################################################################### | |
# USB Drive File Copy | |
echo -e "${BoldBlue}Preparing USB.${NoColour}" | |
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 USB drive | |
diskutil eraseDisk MS-DOS "${usb_label}" MBR ${usb_disk} || { echo -e ${errors[2]}; exit 1; } | |
echo -e "${BoldBlue}USB formatted. Checking mount status...${NoColour}" | |
diskutil list # Debugging output to check mount status | |
# Rsync - Copy files to USB | |
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; } | |
echo -e "${BoldBlue}Rsync complete. Ready to split install.wim...${NoColour}" | |
# Wimlib - Split install.wim into smaller files | |
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; } | |
# Eject the mounted volumes | |
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