snork.ca: Welcome to the brown age of computing! Mainly Clear, 24.9°C [W: 27°C] - No precip

Bash Script To Make USB Installers From Windows ISOs 2020-12-31


Recently a buddy of mine gave me an old tablet to mess with. I ended up getting it to work reasonably well, but in order to do so I needed a PC with some software on it and that software doesn't run on systemd with GNU utilities and Linux applications. So I had to put Windows 7 on a laptop, and then do the Windows 10 upgrade. One of the most painful parts of this is just creating a working Windows installer USB stick. I tried looking for a reasonable Linux-native application to make this easy... but they're a mess, and they certainly don't exist in the Debian repos. Eventually I found this thornelabs.net post explaining a manual procedure that works.

It has been a couple of days, and I have been using the tablet [a bit], but I figured I should find a way to automate the instructions that worked so I can easily make new USB installers later on if I need to. So, I made a batch script. The bad news is that I had to put in a fair bit of checking for things like non-existent ISO file, incorrect device selection, etcetera. The good news is, I tested it on Buster and it worked just fine.

myfreakinimage Goodbye 2020.

iso2usb.sh #!/bin/bash
# Create a Windows USB installer from an ISO file.
# Basically automates these steps: https://thornelabs.net/posts/create-a-bootable-windows-7-or-10-usb-drive-in-linux.html
# Intended for use on apt based systems, tested on Debian Buster.
# Snork: 2020-12-31

export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'

if [ "$#" != "2" ]; then
  echo "-----------------------------------------------------------------------"
  echo "-- iso2usb: Create a Windows USB installer from an ISO file.         --"
  echo "-- Syntax: iso2usb </path/to/windows.iso> <usb device>               --"
  echo "-- Example: iso2usb \"/Downloads/windows10.iso\" \"/dev/sdb\"            --"
  echo "-- WARNING: This will destroy all data on your USB stick!            --"
  echo "-----------------------------------------------------------------------"
  echo ""
  echo "This information may help you determine which device is your USB stick:"
  echo ""
  lsblk -o NAME,MAJ:MIN,SIZE,FSTYPE,MOUNTPOINT,LABEL,HOTPLUG
else
# Is script being run as root or via sudo?
  if [ `id -u` != 0 ]; then
    echo "This script needs to be run as root or using sudo so it can write to the USB drive."
  else
# Does iso path and name look right?
    if [ -f $1 ]; then
      echo "ISO exists..."
    else
      echo "Can't find ISO, must exit"
      exit 1
    fi
# Does device name look right?
    THEDEV=`echo $2 | rev | cut -d "/" -f 1 | rev`
    lsblk | grep $THEDEV > /dev/null
    if [ $? -ne 0 ]; then
      echo "Device $2 does not seem to exist, must exit."
      exit 1
    fi
    echo "Device seems to exist..."
    if [[ `echo "$2" | rev | cut -c 1` =~ [0-9] ]]; then
    echo "WARNING: Your device name ends with a number which is probably a partition."
    echo "         You should specify the base device rather than a partition on it."
    read -r -p ' Hit Y to continue anyways or N to quit: ' rusure
      case "$rusure" in
        y|Y) echo "Whatever you say champ..." ;;
        *) echo "Gotcha... quitting." && exit 1 ;;
      esac
    fi
# Are required applications installed?
    fdisk --version > /dev/null
    if [ $? -ne 0 ]; then
      echo "WARNING: fdisk not installed..."
      INSFD="true"
    fi
    mkfs.ntfs --version > /dev/null
    if [ $? -ne 0 ]; then
      echo "WARNING: ntfs-3g not installed..."
      INSMK="true"
    fi
    ms-sys --version > /dev/null
    if [ $? -ne 0 ]; then
      echo "WARNING: ms-sys not installed (requires wget, gcc, make, and gettext)..."
      INSMS="true"
    fi
# Do you want to install the required applications?
    if [ "$INSFD" = "1" ] || [ "$INSMK" = "1" ] || [ "$INSMS" = "1" ]; then
      echo "WARNING: The required applications listed above are not installed!"
      read -r -p ' Hit Y to install dependencies or N to quit: ' rusure
        case "$rusure" in
          y|Y) echo "Okay champ..." ;;
          *) echo "Gotcha... quitting." && exit 3 ;;
        esac

      apt-get update
      if [ $INSFD = 1 ]; then
        apt-get install -y fdisk
      fi
      if [ $INSMK = 1 ]; then
        apt-get install -y ntfs-3g
      fi
      if [ $INSMS = 1 ]; then
        apt-get install -y gcc make gettext wget
        mkdir /tmp/iso2usb-ms-sys
        cd /tmp/iso2usb-ms-sys
        wget -O ms-sys-2.7.0.tar.gz https://sourceforge.net/projects/ms-sys/files/ms-sys%20development/2.7.0/ms-sys-2.7.0.tar.gz/download
        tar xf ms-sys-2.7.0.tar.gz
        cd ms-sys-2.7.0
        make
        make install
        cd /tmp
        rm -R iso2usb-ms-sys
      fi
    fi
  fi

# Everything is installed, let's do it!
  echo "Last chance to abort, this will destroy all data on $2"
  read -r -p "Hit Y to do it or N to quit: " rusure
    case "$rusure" in
      y|Y) echo "Booyeah do it..." ;;
      *) echo "Gotcha... quitting." && exit 4 ;;
    esac

  echo "Partitioning drive..."
  (
    echo o # Create a new empty DOS partition table
    echo n # Add a new partition
    echo p # Primary partition
    echo 1 # Partition number
    echo   # First sector (Accept default: 1)
    echo   # Last sector (Accept default: varies)
    echo t # Set partition type
    echo 7 # NTFS
    echo a # Set partition bootable
    sleep 3 # Wait a few seconds before writing changes
    echo w # Write changes
  ) | fdisk $2

  echo "Wait a few seconds before formatting..."
  sleep 3
  echo "Formatting partition..."
  DEVPART="${2}1"
  mkfs.ntfs -f $DEVPART
  echo "Adding MBR and EBR to drive..."
  ms-sys -7 $2
  ms-sys -n $DEVPART
  echo "Create and mount ISO and USB..."
  rm -R /tmp/ss-usb
  rm -R /tmp/ss-iso
  mkdir -p /tmp/ss-usb
  mkdir -p /tmp/ss-iso
  mount $DEVPART /tmp/ss-usb
  mount -o loop $1 /tmp/ss-iso
  echo "Copying files..."
  cp -av /tmp/ss-iso/* /tmp/ss-usb
  echo "Unmounting ISO and USB..."
  echo "Seriously, wait for this to finish..."
  umount /tmp/ss-usb
  umount /tmp/ss-iso
  echo "Done."
fi

If anyone has any suggestions, I'm open to potential changes, just let me know eh.

Made with Notepad++ & FastStone, without javascript, cookies, or Clippy's help. Hosted on Devuan with nginx & powered by NK shrooms.