Featured image of post Windows 10のインストーラーをPxEで起動できるようにした

Windows 10のインストーラーをPxEで起動できるようにした

目次

お友達のすてさんが書いてくれました。

はじめに

こんにちは、すてさんです。何を血迷ったのか、Windows 10のインストーラーをPxEで起動できるようにしたので、色々書いていきたいと思います。

なんでこんなことになったのか

おうちにパソコンが余っていました。そして、なぜかパソコンを買ってきました。Windows10のインストーラーが入ったUSBがなぜか起動しなかったので、作り直しました。毎回作り直しているような気がするので、どうせなら、ということで余っているパソコンをPxEサーバーに仕立て上げました。

なにをやったか

いろんなサイトを参考にしたので全部乗せたいのですが、忘れたので、割愛します。

とりあえずサクッと説明すると、PxEブートする端末が、DHCPでiPxEがあるサーバーのIPを取得し、tftpとかでiPxE本体をダウンロードし、起動します。iPxEが起動すると、またDHCPを使ってiPxEスクリプトがあるサーバーのURLを取得し、実行します。iPxEスクリプトにWindows PEを起動するイメージとかを取得する手順を書いておくと、起動します。起動したWindows PEをWindows 10のインストールイメージを展開したやつを置いてあるSambaサーバーに接続し、setup.exeを実行します。あとはやるだけ。

DHCPとtftp

dnsmasqを使いました。一般のご家庭なので、既にDHCP機能を持ったルーターがネットワーク上に存在しています。それの機能を妨害すると家族から苦情が入るため、PxEの部分だけを使うようにしました。

iPxE

PxEサーバーを立てて特定バージョンのWindowsしか起動しないのはもったいなさすぎるので、iPxEを使いました。これを使うと簡単に複数のOSをネットワーク経由で起動できてめっちゃ便利です。便利。

Nginx

iPxEスクリプトの提供に使います。ApacheでもCaddyでも大丈夫だと思います。

Samba

Sambaを使うと、ネットワーク上のファイルをディスクのように扱うことができるので、直接exeが起動できるようになります。本当は回避したかったのですが、難しそうだったので諦めてSambaを使いました。

くわしく

余っていたパソコンにはなぜかWindows 10が入っていたので、吹き飛ばしてUbuntu Serverを入れました。便利ですよね。 とりあえず、

sudo apt install dnsmasq

でdnsmasqが入ります。入りますが、53番ポートが埋まっていて怒られると思います。systemd-resolvedを止めたらなんとかなりますが、インターネットが死ぬので適当に/etc/resolv.conf

nameserver 192.168.11.1 #DNSサーバーにしておく

とかにすると、たぶんなんとかなると思います。

/etc/dnsmasq.d/config.confあたりに

dhcp-range=192.168.11.0,proxy #IPは各々変更してください

#Detect ipxe
dhcp-match=set:ipxe,175

#Detect BIOS
dhcp-match=set:bios,option:client-arch,0

#for bios-es
dhcp-boot=tag:!ipxe,tag:bios,undionly.kpxe #後で配置します

#for efi-s
dhcp-boot=tag:!ipxe,tag:!bios,ipxe.efi #後で配置します

#for iPxE
dhcp-boot=tag:ipxe,http://192.168.11.31/boot.ipxe,192.168.11.31,192.168.11.31 #Nginxを入れるサーバーのIP、各々変えてください

pxe-service=tag:!ipxe,tag:BIOS,x86PC,"splash",undionly.kpxe
pxe-service=tag:!ipxe,tag:!BIOS,x86-64_efi,"splash",ipxe.efi

enable-tftp

tftp-root=/var/www/pxe/tftp #どこでも可
log-queries
log-dhcp
log-facility=/var/log/dnsmasq/dnsmasq.log  #log-queries、log-dhcp、log-facilityはログが要らなければ消してOK
conf-dir=/etc/dnsmasq.d

設定を反映するために再起動します。

sudo systemctl restart dnsmasq

をやっておくといいかもしれません。

後で配置する、と言ったものを配置します。iPxEはソースからビルドするのがいいらしいので、ビルドします。ビルドが面倒な人は、ipxe.orgを探すとビルド済みのバイナリが落ちてると思います。

sudo apt install build-essensial # 足りないかも、足りなかったら探してください。
git clone https://github.com/ipxe/ipxe.git
cd ipxe/src
make bin/undionly.kpxe # BIOSシステム用のファイル
make bin-x86_64-efi/ipxe.efi # UEFIシステム用のファイル

ビルドしたundionly.kpxeipxe.efiを配置します。たぶん~/ipxe/src/bin/undionly.kpxe~/ipxe/src/bin-x86_64-efi/ipxe.efiにあるので、それをtftp-rootにコピーします。

#一例
sudo mkdir -p /var/www/pxe/tftp
sudo cp ~/ipxe/src/bin/undionly.kpxe /var/www/pxe/tftp/
sudo cp ~/ipxe/src/bin-x86_64-efi/ipxe.efi /var/www/pxe/tftp/

この時点で上手くいっていればiPxEが起動すると思います。起動して、iPxEスクリプトが存在しない、と怒られると思います。

ここで、Windows 10をダウンロードします。Rufusを使うと任意のバージョンの任意の言語のWindows 10がダウンロードできるので、適当に選んでダウンロードします。ダウンロードしたらscpとかで転送しておきます。

Windows PEで起動時に実行するスクリプトを先に書きます。Windows PEはめっちゃちっちゃいWindowsです。ここではboot.cmdという名前で保存しておきます。

wpeinit
cmd.exe

Windows PEのイメージを作ります。

sudo apt install wimtools
sudo mount /path/to/Win10.iso /mnt
mkwinpeimg -W /mnt -a amd64 -s boot.cmd winpe.img
sudo umount /mnt 

wimbootを持ってきます。これがあるとWindowsが起動できるらしいです。GitHubから最新版を借りてきます。これはビルドしませんでした。ビルドしてもたぶん大丈夫です。

Nginxを入れて、iPxEスクリプトを作っていきます。

sudo apt install nginx

適当に/etc/nginx/conf.dpxe.confとかを作って、

server {
        listen 80;

        server_name 192.168.11.31; #固定しよう

        root /var/www/pxe; #変えても良い
        index index.html;

        location / {
                try_files $uri $uri/ =404;
        }
}

とかを書いておきます。

/var/www/pxe/win/に、さっき作ったWindows PEのイメージとwimbootを置きます。

Windows PEのイメージから必要なファイルを取り出し、/var/www/pxe/win/winpe/に、配置します

sudo mount winpe.img /mnt
sudo cp -r /mnt/boot /mnt/sources /var/www/pxe/win/winpe/
sudo umount /mnt

/var/www/pxe/boot.ipxeとかを作って、

#!ipxe

dhcp
# Some menu defaults
set menu-timeout 300000
isset ${menu-default} || set menu-default exit

:start

menu Please choose an type of node you want to install
item --gap --           -------------------------- node type -------------------------
item --key w windows    Boot Windows PE
#ここに色々足していくといろいろ起動できる
item --gap --           -------------------------- Advanced Option --------------------
item shell              Drop to iPXE shell
item reboot             Reboot Computer
item exit               Exit menu
choose --timeout ${menu-timeout} --default ${menu-default} selected || goto cancel
goto ${selected}


:windows
kernel win/wimboot
initrd win/winpe/boot/bcd BCD
initrd win/winpe/boot/boot.sdi boot.sdi
initrd win/winpe/sources/boot.wim boot.wim
boot

:shell
echo Type 'exit' to get the back to the menu
shell
set menu-timeout 0
goto start

:reboot
reboot

:exit
exit

みたいなことを書くと、iPxEが何かを表示してくれるようになります。内容はよく理解していないので、ちゃんと理解したかったらググってください。

Windows 10のインストーラーをWindows PEが取得できるようにするために、ファイルを配置して、Sambaを入れます。

sudo apt install samba

sudo mount /path/to/Win10.iso /mnt
sudo cp -r /mnt /var/www/pxe/smb/win10/

/etc/samba/smb.confを編集します。最後の方に、

[public]
  public=yes
  path=/var/www/pxe/smb/ #変えても良い
  browseable=yes

を追記すると、たぶんユーザー無し(=ゲストユーザー)でアクセスできるようになります。

sudo systemctl restart smbd

をやっておくといいかもしれません。

この時点で、上手く行っていいれば、同一LAN内にある端末をPxEブートをするとWindows PEが起動し、コマンドプロンプトに出迎えられると思います。

出迎えられたコマンドプロンプトに、

net use n: \\192.168.11.31\public
n:\win10\setup.exe

を入れると、おなじみのやつが起動して、インストールできると思います。IPは各々変えてください。

おわりに

だいぶ長くなりました。書いていて疲れました。

Windows PEが起動して喜ぶすてさん

起動画面に感動するすてさん

コマンドプロンプトに出迎えられるすてさん

以上です、おわり。

Built with Hugo
テーマ StackJimmy によって設計されています。