Create a Windows 10 installation USB stick from Linux

Today I had to install Windows 10 on a new SSD for my family.

Unpacking the image onto an NTFS partition (didn’t boot)

Since I only have Linux on all of my machines, I tried first my usual way, that is

# run fdisk and create a single NTFS partition
fdisk /dev/sdX
# make a filesystem
mkfs.ntfs -f /dev/sdX1
# mount ISO and USB stick
mkdir -p /mnt/{iso,usb}
mount -o loop win.iso /mnt/iso
mount /dev/sdX1 /mnt/usb
# copy files
cp -r /mnt/iso/* /mnt/usb/
# unmount USB stick
umount /mnt/usb

The hidden rock is: in general this way does not have to work on every machine since UEFI does not neccessarily support NTFS (most in fact don’t, I was just lucky until today).

Loading UEFI driver for NTFS

The obviuos workaround is to create a small ESP partition on the USB stick with, format it in FAT, and put a UEFI shell and a UEFI NTFS driver. After this the procedure is the following.

(EDK2 shell)$ load FS0:\efi\ntfs_x64.efi
(EDK2 shell)$ map -r
(EDK2 shell)$ FS1:\efi\boot\bootx64.efi

Notice that in contrast to the documentation one should load this driver without -nc option.

The Windows installer was loaded successfully, however the installation failed on the partitioning stage with an abosultely uninformative error “Windows cannot be installed to Disk 0 Partition 1”. Most probably the NTFS driver loaded before was unloaded

Unpacking the image onto a FAT partition

The last way I tried worked out. One has to create a big FAT partition and copy in there the content of Windows installation ISO recompressing along the way the biggest file sources/install.wim to make it less than 4GB (otherwise it cannot be copied onto a FAT partition):

# run fdisk and create a single FAT partition
fdisk /dev/sdX
# make a filesystem
mkfs.fat /dev/sdX1
# mount ISO and USB stick
mkdir -p /{mnt,tmp}/iso /mnt/usb
mount -o loop win.iso /mnt/iso
mount /dev/sdX1 /mnt/usb
# recompress install.wim
cp /mnt/iso/sources/install.wim /tmp
wimlib-imagex optimize /tmp/install.wim --solid
# copy files
rsync -av --progress /mnt/iso /mnt/usb --exclude /mnt/iso/sources/install.wim
cp /tmp/install.wim /mnt/usb
# unmount USB stick
umount /mnt/usb

The USB stick is finally ready and the installation went successful all the way.

Other solutions solutions

As I was told later, I could do it in a similar way but just splitting sources/install.wim via wimlib-imagex split instead of recompressing ше (which is quite painful on an ultrabook). Another super easy way to get rid of this headache is to use some black magick called Ventoy. I wish I knew about Ventoy before I started.

P.S. Microsoft, please learn how to make hybrid ISOs in 2021.