Skip to content

Instantly share code, notes, and snippets.

@eddy-geek
Last active August 6, 2025 18:57
Show Gist options
  • Save eddy-geek/1e54105ea87ecc0932203480156e7f58 to your computer and use it in GitHub Desktop.
Save eddy-geek/1e54105ea87ecc0932203480156e7f58 to your computer and use it in GitHub Desktop.
#!/bin/bash
set -e # Exit on any error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Check if running as root
if [[ $EUID -eq 0 ]]; then
print_error "This script should not be run as root"
exit 1
fi
# Check if wimlib is installed
if ! command -v wimlib-imagex &> /dev/null; then
print_error "wimlib is not installed. Install it with: brew install wimlib"
exit 1
fi
# Set ISO path
ISO_PATH="$HOME/Downloads/Win11_24H2_French_x64.iso"
# Check if ISO exists
if [[ ! -f "$ISO_PATH" ]]; then
print_error "ISO file not found at: $ISO_PATH"
exit 1
fi
print_info "Windows USB Creator Script"
print_info "ISO file: $ISO_PATH"
echo
# List available disks
print_info "Available disks:"
diskutil list | grep -E "^/dev/disk[0-9]+ \(external"
echo
# Ask user to select USB drive
while true; do
read -p "Enter the disk identifier for your USB drive (e.g., disk2): " DISK_ID
# Validate input
if [[ ! "$DISK_ID" =~ ^disk[0-9]+$ ]]; then
print_error "Invalid disk identifier format. Use format like 'disk2'"
continue
fi
# Check if disk exists and is external
if ! diskutil info "$DISK_ID" &>/dev/null; then
print_error "Disk $DISK_ID not found"
continue
fi
# Get disk info
DISK_INFO=$(diskutil info "$DISK_ID")
if ! echo "$DISK_INFO" | grep -q "Location.*External"; then
print_warning "Disk $DISK_ID doesn't appear to be external"
read -p "Are you sure you want to continue? (y/N): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
continue
fi
fi
# Show disk info and confirm
DISK_SIZE=$(echo "$DISK_INFO" | grep "Disk Size" | head -1)
DISK_NAME=$(echo "$DISK_INFO" | grep "Volume Name" | head -1 || echo "Volume Name: (Unknown)")
echo
print_info "Selected disk: /dev/$DISK_ID"
print_info "$DISK_SIZE"
print_info "$DISK_NAME"
print_warning "ALL DATA ON THIS DISK WILL BE ERASED!"
echo
read -p "Confirm you want to format /dev/$DISK_ID? (y/N): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
break
fi
done
# Mount the ISO
print_info "Mounting ISO file..."
ISO_MOUNT=$(hdiutil mount "$ISO_PATH" | grep -o '/Volumes/.*$' | tail -1)
if [[ -z "$ISO_MOUNT" ]]; then
print_error "Failed to mount ISO"
exit 1
fi
print_success "ISO mounted at: $ISO_MOUNT"
# Try to infer the mounted ISO volume name
ISO_VOLUMES=$(ls /Volumes/ | grep -E "(WIN|WINDOWS|ESD-ISO|CCCOMA_X64FRE)" | head -5)
ISO_VOLUME_COUNT=$(echo "$ISO_VOLUMES" | wc -l | xargs)
if [[ "$ISO_VOLUME_COUNT" -eq 1 ]] && [[ -n "$ISO_VOLUMES" ]]; then
ISO_MOUNT="/Volumes/$ISO_VOLUMES"
print_info "Auto-detected ISO mount: $ISO_MOUNT"
else
print_info "Multiple or unclear ISO volumes detected:"
ls /Volumes/ | grep -v "^Macintosh HD"
echo
read -p "Enter the exact volume name from /Volumes/: " ISO_VOL_NAME
ISO_MOUNT="/Volumes/$ISO_VOL_NAME"
fi
# Verify the ISO mount contains Windows files
if [[ ! -d "$ISO_MOUNT/sources" ]] || [[ ! -f "$ISO_MOUNT/sources/install.wim" ]]; then
print_error "Invalid Windows ISO: missing sources/install.wim"
hdiutil unmount "$ISO_MOUNT" 2>/dev/null || true
exit 1
fi
# Format the USB drive
print_info "Formatting USB drive as ExFAT..."
if ! diskutil eraseDisk ExFAT "WINDOWS11" MBR "$DISK_ID"; then
print_error "Failed to format USB drive"
hdiutil unmount "$ISO_MOUNT" 2>/dev/null || true
exit 1
fi
print_success "USB drive formatted successfully"
# Wait a moment for the system to recognize the new filesystem
sleep 2
# Mount the USB drive
USB_MOUNT="/Volumes/WINDOWS11"
if [[ ! -d "$USB_MOUNT" ]]; then
print_info "Mounting USB drive..."
diskutil mount "${DISK_ID}s1"
sleep 1
fi
if [[ ! -d "$USB_MOUNT" ]]; then
print_error "Failed to mount USB drive at $USB_MOUNT"
hdiutil unmount "$ISO_MOUNT" 2>/dev/null || true
exit 1
fi
# Copy files from ISO to USB
print_info "Copying files from ISO to USB drive..."
print_info "This may take several minutes..."
# Use rsync with progress
if ! rsync -av --progress "$ISO_MOUNT/" "$USB_MOUNT/"; then
print_error "Failed to copy files to USB drive"
hdiutil unmount "$ISO_MOUNT" 2>/dev/null || true
diskutil unmount "$USB_MOUNT" 2>/dev/null || true
exit 1
fi
print_success "Files copied successfully"
# Sync to ensure all data is written
print_info "Syncing data to disk..."
sync
# Cleanup
print_info "Cleaning up..."
hdiutil unmount "$ISO_MOUNT" 2>/dev/null || true
# Eject USB drive
print_info "Ejecting USB drive..."
diskutil eject "$DISK_ID"
print_success "Windows 11 USB drive created successfully!"
print_success "You can now safely remove the USB drive and use it to install Windows."
echo
print_info "Boot the target computer from this USB drive to start Windows installation."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment