Install Windows 10 from a Linux server with PXE

When installing Windows 10, It was troublesome to make a USB memory and prepare a CD drive, so I installed it using PXE.

Technology to use

First, I will briefly introduce the technical elements used this time.


** PXE (Preboot eXecution Environment) ** is a mechanism for clients to acquire software from the network and execute it. This PXE client function is implemented in common NICs and can be used for OS installation, etc. Wikipedia


iPXE is an open source network boot firmware. In addition to the PXE client function, some functions have been added.

For details, see This page.

The important thing to use this time is that you can get the software via HTTP and start it.


** WinPE (Windows PE) ** is a small OS that can be used for deploying Windows OS. Functions are limited compared to normal Windows.

Installation overview

This time, we will combine these technologies to install the Windows OS. In the end, it looks like this. image.png

Prepare one Linux server for installation. This time, it is assumed that the new personal computer and the Linux server are connected by L2, and other hosts are not connected.

First, we will create a Linux server.

Linux server construction

This time, I prepared a VM of ** Fedora 33 WorkStation **.

[testing@localhost ~]$ cat /etc/fedora-release 
Fedora release 33 (Thirty Three)

Set the interface to the static IP address ** **. (Internet connection is required to install various software, so it may be necessary to switch back to DHCP depending on the environment.)

[testing@localhost ~]$ ip a sh ens3
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:28:c1:a9 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet brd scope global noprefixroute ens3
       valid_lft forever preferred_lft forever
    inet6 fe80::da34:251a:af7d:962d/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

1. DHCP server, TFTP server settings

First, set up a DHCP server and a TFTP server.

The dnsmasq used this time has a TFTP server function, but it is not used. Install tftpd separately.


#It was included in dnsmasq when Fedora was installed.
$ rpm -q dnsmasq

$ sudo vi /etc/dnsmasq.conf
<Described below>

$ sudo firewall-cmd --add-service dhcp
$ sudo systemctl start dnsmasq

/etc/dnsmasq.conf (excerpt)

#Change the interface to the required interface.

#Appropriate dhcp-Comment out the range.

#Comment out the settings related to iPXE.
#3rd line, dhcp returned to iPXE-Change boot to the URL of the script. The script will be created later.
dhcp-match=set:ipxe,175 # iPXE sends a 175 option.


#This time, get iPXE from Fedora Repository.
$ sudo dnf install ipxe-bootimgs
$ rpm -ql ipxe-bootimgs
/usr/share/ipxe/undionly.kpxe # <-Use this.

$ sudo dnf install tftp-server

$ sudo firewall-cmd --add-service tftp
$ sudo systemctl start tftp

$ sudo cp /usr/share/ipxe/undionly.kpxe /var/lib/tftpboot/

If you do so far, you should be able to confirm until iPXE starts.

2. WinPE preparation

Now create WinPE. There is a way to create it on Windows, but this time I will try to create it on Linux using ** wimlib **.

At this point, you need a disk image (ISO file) for installing Windows, so download it from Microsoft official and place it on your Linux server.

#For the English version.
$ ls Win10_20H2_v2_English_x64.iso 


# wimlib-Install utils and syslinux.
$ sudo dnf install wimlib-utils
$ sudo dnf install syslinux

#Specify the command when starting WinPE.
$ vi boot.cmd
<Described below>
#Mount the installer appropriately.
$ sudo mount Win10_20H2_v2_English_x64.iso /mnt

$ mkwinpeimg -W /mnt -a amd64 -s boot.cmd winpe.img

#Unmount it.
$ sudo umount /mnt

The boot.cmd file created above. ** Username (testing in the example) is a Linux username, The password (password in the example) will be the Samba password that you will specify later. ** **


ping -n 10 localhost
net use n: \\\testing password /user:testing

You have now created an image of WinPE.

By the way

It may be puzzling to have ping -n 10 localhost, but it is intended for sleep 10. This is a painstaking measure because an error will occur if the network settings are not completed when executing net use ...

3. HTTP server settings

This time I will use Nginx.


$ sudo dnf install nginx

$ sudo firewall-cmd --add-service http
$ sudo systemctl start nginx

Place the files needed to start WinPE. Suddenly, I use software called wimboot.


$ wget
$ unzip
$ sudo cp <Extracted directory>/wimboot /usr/share/nginx/html/

Extract the required files from the WinPE image and place them.


$ sudo mount winpe.img /mnt/
$ sudo cp -r /mnt/boot /mnt/sources /usr/share/nginx/html

Finally, create an iPXE script file. (I referred to the wimboot page.)

iPXE script

#Match the file name returned by DHCP.
$ sudo vi /usr/share/nginx/html/boot.ipxe



kernel wimboot
initrd boot/bcd BCD
initrd boot/boot.sdi boot.sdi
initrd sources/boot.wim boot.wim


Hopefully you can see WinPE booting at this point.

4. Samba settings

Next, set up Samba.


$ sudo dnf install samba

#Set a password. Make it the same as the user name and password described when creating WinPE.
$ sudo smbpasswd -a -U testing
New SMB password:
Retype new SMB password:
Added user testing.

$ sudo firewall-cmd --add-service samba
$ sudo systemctl start smb

Makes it possible to refer to the windows installer. This time we will use the home directory.


$ sudo setsebool -P samba_enable_home_dirs=on

$ cd
#Match the path described when creating WinPE.
$ mkdir installer
$ sudo mount -o context=user_u:object_r:user_home_t:s0 Win10_20H2_v2_English_x64.iso installer/

$ ls installer/
autorun.inf  boot  bootmgr  bootmgr.efi  efi  setup.exe  sources

This completes the Linux server settings.

Installation execution

I will install it. After connecting properly, start a new computer and wait for the installer to start. After the installer starts, it's almost as usual. (If necessary, change the Boot Order at boot time.)

To give an example, let's try it on a virtual machine.

--First, iPXE boots from PXE. (This virtual machine does not have this because iPXE starts from the beginning.) --Next, iPXE gets the script over HTTP and executes it. image.png --WinPE will start. image.png --WinPE connects to Samba and launches the installer. image.png ――The rest is the same as usual. (It seems that some options cannot be selected.)

The installation was completed like this.


I think it was faster to buy a cheap USB memory because it was so clogged. However, it is still fun to start the actual machine with PXE.

Version information etc.

The main software versions used this time are listed.


$ rpm -q dnsmasq

$ rpm -q tftp-server

$ rpm -q nginx

$ rpm -q samba

$ rpm -q ipxe-bootimgs

$ rpm -q wimlib-utils

Recommended Posts

Install Windows 10 from a Linux server with PXE
[Linux] Copy data from Linux to Windows with a shell script
SSH login to the target server from Windows with a click of a shortcut
ODBC access to SQL Server from Linux with Python
I want to install a package from requirements.txt with poetry
(Windows10) Install Linux environment and gnuplot.
Install Python from source with Ansible
Creating a Flask server with Docker
Install Arch Linux on DeskMini A300
Run a Linux server on GCP
Create a Linux environment on Windows 10
[Python Windows] pip install with Python version
[Scp] Copy files locally from Linux server with Tera Term ssh scp
Building a Python3 environment with Amazon Linux2
Install Python as a Framework with pyenv
Set up a Samba server with Docker
Install wsl2 and master linux on windows
Build a simple WebDAV server on Linux
Django + Apache with mod_wsgi on Windows Server 2016
Building a Python 3.6 environment with Windows + PowerShell
Install and Configure TigerVNC server on Linux
Build a CentOS Linux 8 environment with Docker and start Apache HTTP Server
Build a Samba server on Arch Linux
Dockerfile: Install Docker on your Linux server
Install Mecab on Linux (CentOS) with brew
How to install Windows Subsystem For Linux
Install the python module with pip on a server without root privileges
[Linux] Build a jenkins environment with Docker
Create a Linux virtual machine on Windows
Verification of how to periodically execute a script on a Linux server on Windows
Call a command from Python (Windows version)
Rock-paper-scissors with Python Let's run on a Windows local server for beginners
Build Linux on a Windows environment. Steps to install Laradock and migrate
[Linux] Build a Docker environment with Amazon Linux 2
Let's install box2d-py with Windows 10 environment pip
Put Docker in Windows Home and run a simple web server with Python
Until you install Python with pythonbrew and run Flask on a WSGI server
Start a temporary http server locally with Pytest
Send a message from Slack to a Python server
Build a local server with a single command [Mac]
Set up a simple HTTPS server with asyncio
Set up a local server with Go-File upload-
Open a ZIP created on Windows in Linux
Create a game UI from scratch with pygame2!
Install OpenCV 4.0 and Python 3.7 on Windows 10 with Anaconda
Start a simple Python web server with Docker
Pipenv install with ssh from Private Bitbucket Repository
Cross-compile windows version from nim on arch | linux
Pretend to be a server with two PCs
Start a process with a scheduling policy on Linux
Set up a local server with Go-File download-
Launch a web server with Python and Flask
Organize files on Windows with Linux commands-using WSL-
Boot CentOS 8 from Windows 10 with Wake On LAN
Draw a graph with matplotlib from a csv file
Create a decision tree from 0 with Python (1. Overview)
Asynchronous processing with Arduino (Asynchronous processing of processing requests from Linux)
Install vim7.3 (+ python2.4) from source (compatible with Gundo.vim)
Mount a directory on another server with sshfs
Back up from QNAP to Linux with rsync
Read line by line from a file with Python