Skip to content

Instantly share code, notes, and snippets.

@othyn
Last active November 2, 2023 15:25
Show Gist options
  • Save othyn/29b82e39eb8cdd98adf1be77cbb62700 to your computer and use it in GitHub Desktop.
Save othyn/29b82e39eb8cdd98adf1be77cbb62700 to your computer and use it in GitHub Desktop.
Quick script to write a bootable UEFI Windows ISO to USB in macOS
#!/bin/bash
# System: Darwin x86_64 19.6.0 (macOS 10.15.6 19G2021)
# Author: Othyn (https://github.com/othyn)
# Source: https://gist.github.com/othyn/29b82e39eb8cdd98adf1be77cbb62700
# Dependencies: pv, wimlib
# Licence: MIT
DEFAULT="\x1b[0m"
RED="\x1b[31m"
GREEN="\x1b[32m"
YELLOW="\x1b[33m"
newLine () {
printf "\n"
}
printLine () {
printf ">>> ${1}\n"
}
defaultLine () {
printLine "${DEFAULT}${1}"
}
redLine () {
printLine "${RED}${1}${DEFAULT}"
}
greenLine () {
printLine "${GREEN}${1}${DEFAULT}"
}
yellowLine () {
printLine "${YELLOW}${1}${DEFAULT}"
}
# Dependency checks
if ! command -v pv >/dev/null 2>&1 ; then
redLine "Please install pv first, via 'brew install pv' is easiest, then try again."
exit 1
fi
if ! command -v wimlib-imagex >/dev/null 2>&1 ; then
redLine "Please install wimlib first, via 'brew install wimlib' is easiest, then try again."
exit 1
fi
# Check the path to the image to flash was provided
if [[ -z "${1}" ]] ; then
redLine "Please provide the path to the image to flash and try again!"
exit 1
fi
# Set the image path to use
imagePath="${1}"
imageDirname="$(dirname "${imagePath}")"
imageBasename="$(basename "${imagePath}")"
if [[ ! -f "${1}" ]] ; then
redLine "Invalid filepath provided. Please try again!"
exit 1
fi
displayDisks () {
# Clear the console
clear
defaultLine "These are the disks currently available on your system:"
newLine
# Spit out all available disks
diskutil list
}
# Set disk validity
validDisk=false
displayDisks
while [ "$validDisk" = false ]; do
# Ask which disk number they wish to flash
greenLine "Please enter the disk number of the disk you wish to flash: "
read usbDiskNumber
if [[ -e /dev/disk"${usbDiskNumber}" ]]; then
validDisk=true
else
redLine "Disk /dev/disk${usbDiskNumber} not found!"
fi
done
displayDisks
greenLine "Disk /dev/disk${usbDiskNumber} has been selected."
redLine "This disk will be permanently erased!"
yellowLine "Are you sure you want to continue? Y/n: "
read diskWipeConfirm
# Confirm that they want to wipe the selected disk
if [[ "$diskWipeConfirm" != Y ]]; then
greenLine "User didn't want to write, aborting!"
exit 0
fi
usbVolumeName="WINSTALL"
newLine
greenLine "Partitioning the entire of disk${usbDiskNumber} to MBR Fat32 with name '${usbVolumeName}'..."
# Partition the disk as required
diskutil eraseDisk MS-DOS "${usbVolumeName}" MBR /dev/disk"${usbDiskNumber}"
sleep 1
isoMountPath="${HOME}/mount/WINSTALL_SRC"
newLine
greenLine "Mounting ISO to temporary location '${isoMountPath}'..."
if [[ ! -d "${isoMountPath}" ]] ; then
mkdir -p "${isoMountPath}"
else
diskutil unmount "${isoMountPath}"
fi
hdiutil mount -mountPoint "${isoMountPath}" "${imagePath}"
newLine
greenLine "Copying all but install.wim from '${isoMountPath}/' to '/Volumes/${usbVolumeName}'..."
rsync -vha --progress --exclude=sources/install.wim "${isoMountPath}/" "/Volumes/${usbVolumeName}"
newLine
greenLine "Creating install.wim chunks an placing into '/Volumes/${usbVolumeName}/sources'..."
yellowLine "This may take some time and appear to not do anything, bare with it..."
mkdir -p "/Volumes/${usbVolumeName}/sources"
wimlib-imagex split "${isoMountPath}/sources/install.wim" "/Volumes/${usbVolumeName}/sources/install.swm" 4000
newLine
greenLine "Cleaning up temporary mounts and directories..."
diskutil eject "${isoMountPath}"
rm -r "${isoMountPath}"
newLine
greenLine "Flash complete!"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment