Last active
July 4, 2023 05:28
-
-
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 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