How to make Windows 10 USB install media in Linux

Updated: January 4, 2020

The reason why I attempted this thing is a bit convoluted. It started, like any good story, with a problem, a conflict, a conundrum. I had a laptop with a multi-boot system, Windows 10 and a whole bunch of Linux distributions, and it was ill. Not booting. Nothing. I needed to recover it, and recover it I did, one system after another, until only Windows 10 was left and acting rather stubbornly.

I thought using the Windows 10 install media could help, as I'd have better control over the recovery tools and options than using the one that Windows offers on a botched startup. This meant creating bootable media, and this turned out to be more complicated than I thought. I wanted to create the USB media in Linux, without relying on any third-party tools that purport to do this. Why? Because independence. If it works with standard tools, you can use it anywhere. Begin to commence.

Step 1: Download the Windows 10 ISO

This isn't trivial. In Windows, it will only offer the Windows media creation tool. But we want the raw ISO, so you should do this by changing the user agent of your browser, or download the image in a Linux distribution, which is, after all, why we are here! First challenge of the day surmounted with great success.

Step 2: Mount & copy and/or extract the ISO

Once you have the file downloaded, we need to extract it to a writable location, e.g. somewhere in your home directory. If you mount the ISO as a loopback device, it will be read-only, and you will need to manually copy the contents. Some Linux file managers cannot natively extract ISO files. Some can. I had this error:

This disc contains a "UDF" file system and requires an operating system
that supports the ISO-13346 "UDF" file system specification.

All right, we need to do the manual mount & copy:

mount -o loop windows10.iso /mountpoint
cp -r -T /mountpoint/ /home/"user"/windows10data

Step 3: Compress install.wim

The reason we did the above is because one of the files - install.wim - contained in the ISO is larger than 4 GB, and we need to compress it. And the reason for that is, depending on your system firmware, your machine may not be able to boot NTFS-formatted devices (most likely not, in fact). So to be on the safe side, our USB drive needs to be formatted as FAT32, and there's the 4GB limit for file size.

The file is located under sources, so in our case /home/"user"/windows10data/sources/install.wim. To compress the file, we need a tool called wimlib. You ought to find it in your distro's repos. As I was using Kubuntu 18.04 for this task, the package is indeed available.

sudo apt-get install wimtools

Now, the compression step (inside the folder containing the ISO files):

sudo wimlib-imagex optimize install.wim --solid

You may need sudo, because you could encounter an error like this:

[ERROR] Can't modify "/home/roger/win/sources/install.wim": Permission denied
ERROR: Exiting with error code 71:
The WIM is read-only (file permissions, header flag, or split WIM).

And the successful result look like this:

"install.wim" original size: 4463411 KiB
Using LZMS compression with 8 threads
Archiving file data: 9 GiB of 9 GiB (100%) done
"install.wim" optimized size: 3311533 KiB
Space saved: 1151878 KiB

The 4.4GB image was reduced to 3.3GB, a 30% reduction, so this means potentially we have quite some room to grow before this method becomes inadequate for future use with Windows 10 ISO files and the FAT32 filesystem.

Step 4: Prepare USB device

Now, we need a thumb drive, at least 8 GB in size. It needs to be partitioned. You can use a tool like GParted or KDE Partition Manager, or if you're savvy, fdisk or gdisk from the command line, to prepare the device. First, you need to create a new GPT partition table. Second, create a single FAT32 partition. It should not have the boot flag. In other words, it will be identified as "msft-data" partition.

Partition flag

You can also do this on the command line. For example, with gdisk:

sudo gdisk /dev/[your device here]

For example, something like this:

sudo gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help):

Please be EXTRA careful so you don't accidentally initialize a wrong device and ruin your data! In gdisk, you need the following steps:

Once you exit the tool, format the partition:

sudo mkfs.vfat /dev/[your device, partition here]

For instance, /dev/sdb. By default, the mkfs.vfat command will choose the optimal FAT size, but you can override this with the -F flag. However, in most cases, you will not need to make any changes, and you will get the default FAT32 filesystem.

Disk /dev/sdb: 14.9 GiB, 16008609792 bytes, 31266816 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 43479D21-6D76-2CA4-A7BA-596C08A99193

Device     Start      End  Sectors  Size Type
/dev/sdb1   2048 31260671 31258624 14.9G Microsoft basic data

Step 5: Copy data to USB device

Now that we have everything ready, we need to copy the extracted ISO contents with the compressed install.wim file onto the USB drive:

sudo mount /dev/[your device, partition here] /usb/mount/point/
sudo cp -r -T /location/windows10data /usb/mount/point/

One last screenshot, just showing the partition table, contents and whatnot.

Data copied

And everything is ready now. We can proceed to commence to boot.

Step 6: Boot Windows 10 on target device

Bob's your uncle at this point.

Optional: NTFS partition on USB device

Now, you may be wondering how Windows does this "officially" or how different tools (like woeusb or Rufus) manage to handle the larger-than-4GB install.wim file. Well, it is possible to boot NTFS devices on UEFI systems, but this requires some extra steps.

In essence, this involves the use of the UEFI:NTFS bootloader. Without going into too many details, because this is only an optional come-what-may in case you are severely limited with creating and/or using the method listed above, the sequence of steps is as follows (there are alternatives, but this is one way):

Conclusion

There we are, the end of this tutorial. I hope you will find this useful, because quite often, seemingly trivial actions can have unintended convoluted consequences, like we've seen here. If you do not want to rely on third-party tools (much), and want to be able to create Windows 10 USB install media in Linux, this guide provides you with the necessary steps.

We did learn quite some here, including how to manage ISO images, how to compress wim files, how to partition and format devices, and there's even an optional magic trick for booting NTFS devices on UEFI hardware. This is what many USB creation tools do in the background, and now you're in on the secret. Well, that's all for now. Now, off you go installing.

Cheers.

You may also like: