Yet again I had $reason to install Windows 10 to one workstation. As I only have Linux workstations (w/o DVD drives) I had to create installer USB from ISO image provided by Microsoft.

I tried couple methods, a) dd if=windows.iso of=/dev/myusbstick and b) creating FAT32 partition & copying disk contents there. (FAT32 because it’s the requirement for UEFI booting.) … However, after some debugging I found out, that sources/install.wim is more than 4 gigabytes (max filesize limit on FAT32 drives), and neither of above methods worked. So, with some research I found blog post by Microsoft describing various methods for creating UEFI install stick, using Windows. BUT I HAVE NO WINDOWS WORKSTATIONS AVAILABLE.

More research (googling), and I found some tools for handling .wim files. And those were just apt-get install away.

apt-get install wimtools

Especially interesting was tool called wimlib-imagex, which is able to do same tricks as dism in Windows. And I already had that blogpost describing how to split files larger than 4GB. I decided to use parts with maximum size of 250 megabytes.

wimlib-imagex split install.wim install.swm 250

Ie. full process in copy-pasteable format…

# Path to source ISO image.
# <https://www.microsoft.com/software-download/windows10ISO>
export ISOFILE="Win10_1809Oct_EnglishInternational_x64.iso"

# Path to the device that points to your USB stick
# Your modified installer will be written here, "target".
export USBDEVICE="/dev/sdX"

# Temporary directory we create for manipulating the image contents
export TEMPDIR="$(mktemp -d winimage-XXXXXX)"

# Our mountpoint for the ISO image
export SOURCE="source"

# Our mountpoint for the target device
export TARGET="target"

# Install necessary tools
# - parted: for creating disk partitions
# - rsync: for copying files around efficiently
# - wimtools: for manipulating Windows installer contents
apt-get install parted rsync wimtools

# Directory for mounting the ISO image
mkdir "${SOURCE}"

# Directory for mounting the USB stick
mkdir "${TARGET}"

# Create GPT partition table, one FAT32 partition that uses 100% of available space
# first create msdos table to ensure that existing table is purged
parted --script "${USBDEVICE}" mklabel msdos
parted --script "${USBDEVICE}" mklabel gpt
parted --script "${USBDEVICE}" mkpart primary fat32 1 100%
parted --script "${USBDEVICE}" set 1 msftdata on

# Just to make sure that partition is correctly formatted as FAT32
mkfs.vfat "${USBDEVICE}1"

# Mount Windows ISO image for file copying
mount -oloop "${ISOFILE}" "${SOURCE}"

# Mount USB stick, partition 1
mount "${USBDEVICE}1" "${TARGET}"

# Copy all files from ISO image to temporary directory
rsync -avh --no-o --no-g "${SOURCE}/" "${TEMPDIR}/"

# Split the install.wim file to smaller parts (max 250MB), to temporary directory
wimlib-imagex split \
    "${TEMPDIR}/sources/install.wim" \
    "${TEMPDIR}/sources/install.swm" \
    250

# Finally, copy resulting data structure, without large file (install.wim) to
# the USB stick
rsync -avh --no-o --no-g --exclude="install.wim" "${TEMPDIR}/" "${TARGET}/"

# Ensure that everything has been written to disk
sync

# Unmount, your stick is ready now
umount "${SOURCE}"
umount "${TARGET}"
rm -rf "${TEMPDIR}"

Feedback / comments?

Ping me (@ypcs) on Twitter