Git Product home page Git Product logo

Comments (25)

tpw56j avatar tpw56j commented on June 11, 2024 1

Ok, let's start with CentOS 8.
I installed CentOS 8 in my virtual machine and set up the Windows installation. For CentOS 9 with cobbler 3.3.3 the procedure is different and I will describe it later.

Sources for installation:

  1. CentOS-Stream-8-20230825.0-x86_64-dvd1.iso from https://www.centos.org/download
  2. Cobbler 3.2 does not support Windows 11, so Win10_22H2_English_x64v1.iso from https://www.microsoft.com/software-download/windows10

Purpose: to install Windows 10 in a KVM virtual machine (Legacy BIOS Boot).

Step by step:

  1. Install CentOS 8 with Server + GIU. I need a GUI because I'm going to create a virtual machine for Windows using virt-manager.
  2. In my test environment, I can disable selinux and firewall
# setenforce 0
# systemctl stop firewalld
  1. Installing additional repos and packages
# dnf -y install epel-release
# wget https://fedorapeople.org/groups/virt/virtio-win/virtio-win.repo \
  -O /etc/yum.repos.d/virtio-win.repo

# dnf -y install cobbler python3-pefile python3-hivex wimlib-utils \
  virtio-win virt-manager syslinux-tftpboot samba
  1. Prepare tftp
    create /etc/tftpd.rules:
# cat /etc/tftpd.rules
rg	\\			/ # Convert backslashes to slashes
r	(/Boot/Fonts/)(.*)	/winos/Win10_EN-x64/boot/fonts/\2

r	(boot1e.\.exe)		/winos/Win10_EN-x64/\1
r	(/Boot/)(1E.)		/winos/Win10_EN-x64/boot/\2

The values for the rules must match the bcd and bootmgr metadata of the cobbler profile.
Later, at the time of Windows installation, you can see how the remap rules work:

# journalctl -b -u tftp
Aug 29 18:11:04 cobbler.home in.tftpd[6806]: RRQ from ::ffff:192.168.124.180 filename /winos/Win10_EN-x64/win10a.0
Aug 29 18:11:04 cobbler.home in.tftpd[6806]: Client ::ffff:192.168.124.180 finished /winos/Win10_EN-x64/win10a.0
Aug 29 18:11:04 cobbler.home in.tftpd[6807]: remap: input: boot1ea.exe
Aug 29 18:11:04 cobbler.home in.tftpd[6807]: remap: rule 2: rewrite: /winos/Win10_EN-x64/boot1ea.exe
Aug 29 18:11:04 cobbler.home in.tftpd[6807]: remap: done
Aug 29 18:11:04 cobbler.home in.tftpd[6807]: RRQ from ::ffff:192.168.124.180 filename boot1ea.exe remapped to /winos/Win10_EN-x64/boot1ea.exe
Aug 29 18:11:04 cobbler.home in.tftpd[6807]: Client ::ffff:192.168.124.180 finished boot1ea.exe
Aug 29 18:11:04 cobbler.home in.tftpd[6808]: remap: input: \Boot\1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6808]: remap: rule 0: rewrite: /Boot\1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6808]: remap: rule 0: rewrite: /Boot/1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6808]: remap: rule 3: rewrite: /winos/Win10_EN-x64/boot/1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6808]: remap: done
Aug 29 18:11:04 cobbler.home in.tftpd[6808]: RRQ from ::ffff:192.168.124.180 filename \Boot\1Ea remapped to /winos/Win10_EN-x64/boot/1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6808]: tftp: client does not accept options
Aug 29 18:11:04 cobbler.home in.tftpd[6809]: remap: input: \Boot\1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6809]: remap: rule 0: rewrite: /Boot\1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6809]: remap: rule 0: rewrite: /Boot/1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6809]: remap: rule 3: rewrite: /winos/Win10_EN-x64/boot/1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6809]: remap: done
Aug 29 18:11:04 cobbler.home in.tftpd[6809]: RRQ from ::ffff:192.168.124.180 filename \Boot\1Ea remapped to /winos/Win10_EN-x64/boot/1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6809]: Client ::ffff:192.168.124.180 finished \Boot\1Ea
Aug 29 18:11:04 cobbler.home in.tftpd[6812]: remap: input: \winos\Win10_EN-x64\boot\winpe.wim
Aug 29 18:11:04 cobbler.home in.tftpd[6812]: remap: rule 0: rewrite: /winos\Win10_EN-x64\boot\winpe.wim
Aug 29 18:11:04 cobbler.home in.tftpd[6812]: remap: rule 0: rewrite: /winos/Win10_EN-x64\boot\winpe.wim
Aug 29 18:11:04 cobbler.home in.tftpd[6812]: remap: rule 0: rewrite: /winos/Win10_EN-x64/boot\winpe.wim
Aug 29 18:11:04 cobbler.home in.tftpd[6812]: remap: rule 0: rewrite: /winos/Win10_EN-x64/boot/winpe.wim
Aug 29 18:11:04 cobbler.home in.tftpd[6812]: remap: done
Aug 29 18:11:04 cobbler.home in.tftpd[6812]: RRQ from ::ffff:192.168.124.180 filename \winos\Win10_EN-x64\boot\winpe.wim remapped to /winos/Win10_EN-x64/boot/winpe.wim
Aug 29 18:11:04 cobbler.home in.tftpd[6812]: tftp: client does not accept options
Aug 29 18:11:04 cobbler.home in.tftpd[6813]: remap: input: \winos\Win10_EN-x64\boot\boot.sdi
Aug 29 18:11:04 cobbler.home in.tftpd[6813]: remap: rule 0: rewrite: /winos\Win10_EN-x64\boot\boot.sdi
Aug 29 18:11:04 cobbler.home in.tftpd[6813]: remap: rule 0: rewrite: /winos/Win10_EN-x64\boot\boot.sdi
Aug 29 18:11:04 cobbler.home in.tftpd[6813]: remap: rule 0: rewrite: /winos/Win10_EN-x64/boot\boot.sdi
Aug 29 18:11:04 cobbler.home in.tftpd[6813]: remap: rule 0: rewrite: /winos/Win10_EN-x64/boot/boot.sdi
Aug 29 18:11:04 cobbler.home in.tftpd[6813]: remap: done
Aug 29 18:11:04 cobbler.home in.tftpd[6813]: RRQ from ::ffff:192.168.124.180 filename \winos\Win10_EN-x64\boot\boot.sdi remapped to /winos/Win10_EN-x64/boot/boot.sdi
# cp /usr/lib/systemd/system/tftp.service /etc/systemd/system
# vi /etc/systemd/system/tftp.service
# cat /etc/systemd/system/tftp.service
[Unit]
Description=Tftp Server
Requires=tftp.socket
Documentation=man:in.tftpd

[Service]
ExecStart=/usr/sbin/in.tftpd -m /etc/tftpd.rules -v -v -v -s /var/lib/tftpboot
StandardInput=socket

[Install]
Also=tftp.socket

# systemctl daemon-reload
# systemctl start tftp.socket
# cp /tftpboot/* /var/lib/tftpboot
  1. Cobbler settings
# ifconfig virbr0
virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.124.1  netmask 255.255.255.0  broadcast 192.168.124.255
        ether 52:54:00:41:0c:c5  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
--- settings.yaml.orig
+++ settings.yaml
@@ -252,7 +252,7 @@
 # if using Cobbler with manage_dhcp, put the IP address
 # of the Cobbler server here so that PXE booting guests can find it
 # if you do not set this correctly, this will be manifested in TFTP open timeouts.
-next_server: 127.0.0.1
+next_server: 192.168.124.1
 
 # settings for power management features.  optional.
 # see https://github.com/cobbler/cobbler/wiki/Power-management to learn more
@@ -350,7 +350,7 @@
 # if you have a server that appears differently to different subnets
 # (dual homed, etc), you need to read the --server-override section
 # of the manpage for how that works.
-server: 127.0.0.1
+server: 192.168.124.1

Cobbler 3.2 has a bug in sync_post_wingen.py that was fixed in new versions but not backported in 3.2.
Remove the extra space at the end of 2 lines in /usr/lib/python3.6/site-packages/cobbler/modules/sync_post_wingen.py:

--- sync_post_wingen.py.orig
+++ sync_post_wingen.py
@@ -97,7 +97,7 @@
                           "value": guid + b"\x00\x00\x00\x00\x01\x00\x00\x00"
                                         + winpath_length(wim, 126)
                                         + b"\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-                                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00 "
+                                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
                                         + winpath_length(wim, 86)
                                         + b"\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00"
                                           b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
@@ -110,7 +110,7 @@
                           "t": REG_BINARY,
                           "value": guid + b"\x00\x00\x00\x00\x01\x00\x00\x00" + winpath_length(wim, 126)
                                         + b"\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-                                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00 "
+                                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
                                         + winpath_length(wim, 86)
                                         + b"\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00"
                                           b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
# systemctl start httpd
# systemctl start cobblerd

# cobbler version
Cobbler 3.2.2
  source: ?, ?
  build time: Wed Apr  5 15:54:53 2023
  1. Prepare libvirt default network for network boot
# virsh net-destroy default
Network default destroyed

add the line <bootp file='pxelinux.0'/> to the network definition

# virsh net-edit default
Network default XML configuration edited.

# virsh net-dumpxml default
<network>
  <name>default</name>
  <uuid>cc114d1e-0e60-4a17-9b5f-65126f5db66b</uuid>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:41:0c:c5'/>
  <ip address='192.168.124.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.124.2' end='192.168.124.254'/>
      <bootp file='pxelinux.0'/>
    </dhcp>
  </ip>
</network>

# virsh net-start default
Network default started
  1. Prepare Windows distro
# mkdir /mnt/win10
# mount -o loop,ro Win10_22H2_English_x64v1.iso /mnt/win10
# wimexport /mnt/win10/sources/boot.wim 1 winpe.wim --boot
Using LZX compression with 2 threads
Archiving file data: 943 MiB of 943 MiB (100%) done

# mkdir -p /var/lib/tftpboot/winos/Win10_EN-x64
# rsync -av /mnt/win10/ /var/lib/tftpboot/winos/Win10_EN-x64
# mv /var/lib/tftpboot/winos/Win10_EN-x64/boot/bcd /var/lib/tftpboot/winos/Win10_EN-x64/boot/BCD
# wimextract winpe.wim 1 /Windows/Boot/PXE/pxeboot.n12 /Windows/Boot/PXE/bootmgr.exe --dest-dir=/var/lib/tftpboot/winos/Win10_EN-x64 --no-acls --no-attributes
Extracting file data: 680 KiB of 680 KiB (100%) done
Done extracting files.

# wimextract winpe.wim 1 /Windows/System32/config/SOFTWARE --no-acls --no-attributes
Extracting file data: 9216 KiB of 9216 KiB (100%) done
Done extracting files.

Changing registry values with hivexsh is not very easy because you have to update the entire registry node even though some of the values don't change.
We need to change the Microsoft\Windows NT\CurrentVersion\SystemRoot value from X:\$windows.~bt\Windows to x:\Windows and delete SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinPE\InstRoot.

# hivexsh -w SOFTWARE
SOFTWARE\> cd Microsoft\Windows NT\CurrentVersion
SOFTWARE\Microsoft\Windows NT\CurrentVersion> lsval
"SystemRoot"="X:\\$windows.~bt\\Windows"
"BaseBuildRevisionNumber"=dword:00000001
"BuildBranch"="vb_release"
"BuildGUID"="ffffffff-ffff-ffff-ffff-ffffffffffff"
"BuildLab"="19041.vb_release.191206-1406"
"BuildLabEx"="19041.1.amd64fre.vb_release.191206-1406"
"CurrentBuild"="19041"
"CurrentBuildNumber"="19041"
"CurrentMajorVersionNumber"=dword:0000000a
"CurrentMinorVersionNumber"=dword:00000000
"CurrentType"="Multiprocessor Checked"
"CurrentVersion"="6.3"
"EditionID"="WindowsPE"
"EditionSubManufacturer"=""
"EditionSubstring"=""
"EditionSubVersion"=""
"InstallationType"="WindowsPE"
"InstallDate"=dword:00000000
"ProductName"="Windows (TM) 10 Preinstallation Environment"
"ReleaseId"="2004"
"SoftwareType"="System"
"UBR"=dword:00000b95
SOFTWARE\Microsoft\Windows NT\CurrentVersion> lsval
"SystemRoot"="x:\\Windows"
"BaseBuildRevisionNumber"=dword:00000001
"BuildBranch"="vb_release"
"BuildGUID"="ffffffff-ffff-ffff-ffff-ffffffffffff"
"BuildLab"="19041.vb_release.191206-1406"
"BuildLabEx"="19041.1.amd64fre.vb_release.191206-1406"
"CurrentBuild"="19041"
"CurrentBuildNumber"="19041"
"CurrentMajorVersionNumber"=dword:0000000a
"CurrentMinorVersionNumber"=dword:00000000
"CurrentType"="Multiprocessor Checked"
"CurrentVersion"="6.3"
"EditionID"="WindowsPE"
"EditionSubManufacturer"=""
"EditionSubstring"=""
"EditionSubVersion"=""
"InstallationType"="WindowsPE"
"InstallDate"=dword:00000000
"ProductName"="Windows (TM) 10 Preinstallation Environment"
"ReleaseId"="2004"
"SoftwareType"="System"
"UBR"=dword:00000b95

SOFTWARE\Microsoft\Windows NT\CurrentVersion> cd WinPE
SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinPE> lsval
"Version"="10.0.19041.1"
"CustomBackground"=str(2):"%systemroot%\\system32\\winre.jpg"
"InstRoot"="X:\\$windows.~bt\\"
SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinPE> setval 2
  key> Version
value> string:10.0.19041.1
  key> CustomBackground
value> expandstring:%systemroot%\system32\winre.jpg
SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinPE> lsval
"Version"="10.0.19041.1"
"CustomBackground"=str(2):"%systemroot%\\system32\\winre.jpg"
SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinPE> commit
SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinPE> exit

# wimupdate winpe.wim 1 --command="add SOFTWARE /Windows/System32/config/SOFTWARE"
Scanning "SOFTWARE" (loading as WIM path: "/Windows/System32/config/SOFTWARE")...
9216 KiB scanned (1 files, 0 directories)    
Updating "/Windows/System32/config/SOFTWARE" in WIM image
Using LZX compression with 2 threads
Archiving file data: 9216 KiB of 9216 KiB (100%) done

Note: the tedious previous commands of step 7 in cobbler 3.3 are done by cobbler import.

I'm going to use RedHat's paravirtualized drivers for KVM, so I put them on a windows share and install the network and storage drivers in a WinPE image.


# mkdir -p /var/lib/tftpboot/winos/Drivers/Virt/Win10
# cp /usr/share/virtio-win/drivers/by-os/amd64/w10/* /var/lib/tftpboot/winos/Drivers/Virt/Win10

From /var/lib/tftpboot/winos/win_sif.template:

        <component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmln
s:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DriverPaths>
                <PathAndCredentials wcm:action="add" wcm:keyValue="1">
#if $os_version == '7'
                    <Path>\\@@http_server@@\WINOS\Drivers\Virt\Win7</Path>
#else if $os_version == '8'
                    <Path>\\@@http_server@@\WINOS\Drivers\Virt\Win8</Path>
#else if $os_version == '10'
                    <Path>\\@@http_server@@\WINOS\Drivers\Virt\Win10</Path>
#else if $os_version == '2008'
                    <Path>\\@@http_server@@\WINOS\Drivers\Virt\2008</Path>
#else if $os_version == '2012'
                    <Path>\\@@http_server@@\WINOS\Drivers\Virt\2012</Path>
#else if $os_version == '2016'
                    <Path>\\@@http_server@@\WINOS\Drivers\Virt\2016</Path>
#else if $os_version ==  '2019'
                    <Path>\\@@http_server@@\WINOS\Drivers\Virt\2019</Path>
#end if
                </PathAndCredentials>
            </DriverPaths>
        </component>

In order to install drivers in a WinPE image, you will have to use Windows with AIK installed
Снимок экрана от 2023-08-29 17-44-14

# cp winpe.wim /var/lib/tftpboot/winos/winpe8.template
  1. Samba share
    Add the following lines to the end of /etc/samba/smb.conf:
[WINOS]
        path = /var/lib/tftpboot/winos
        guest ok = yes
        browseable = yes
        public = yes
        writeable = no
        printable = no
# systemctl start smb
# systemctl start nmb
  1. Prepare Windows templates
    /var/lib/tftpboot/winos/startnet.template - is used to create /Windows/System32/startnet.cmd in the corresponding wim image for the profile.
    It might look something like this:
wpeinit

ping 127.0.0.1 -n 10 >nul
#set $distro_dir = '\\\\' + $http_server + '\\WINOS\\' + $distro_name
net use z: $distro_dir
set exit_code=%ERRORLEVEL%
IF %exit_code% EQU 0 GOTO INSTALL
echo "Can't mount network drive"
goto EXIT

:INSTALL
set n=0
#set $unattended = "Z:\\sources\\" + $kernel_options["sif"]
z:\sources\setup.exe /unattend:$unattended
set /a n=n+1
ping 127.0.0.1 -n 5 >nul
IF %n% lss 20 goto INSTALL

:EXIT

/var/lib/tftpboot/winos/win_sif.template - is used to create a Windows installation response xml file.
Example: https://github.com/cobbler/cobbler/blob/main/templates/windows/answerfile.template
Trigger sync_post_wingen.py creates a response file from win_sif.template and copies it to /var/lib/tftpboot/winos/$distro_name/$kernel_options["sif"] where it expects to be found through the Windows share startnet.cmd to start the installation.

/var/lib/tftpboot/winos/post_inst_cmd.template - is used to create a script that runs after the Windows installation is complete. post_inst_cmd has no profile-specific and therefore its location is specified in the distro metadata. In order for the Windows installer to copy it to the computer being installed, sync_post_wingen.py places it in sources/$OEM$/$1 relative to the distribution directory. post_inst_cmd is started because it is specified in the <FirstLogonCommands> section of the response file:

            <FirstLogonCommands>
                <SynchronousCommand wcm:action="add">
                    <RequiresUserInput>false</RequiresUserInput>
                    <Order>1</Order>
                    <CommandLine>c:\post_install.cmd @@profile_name@@</CommandLine>
                </SynchronousCommand>
            </FirstLogonCommands>
            <AutoLogon>
                <Password>
                    <Value>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</Value>
                    <PlainText>false</PlainText>
                </Password>
                <Enabled>true</Enabled>
                <Domain>WORKGROUP</Domain>
                <Username>User</Username>
                <LogonCount>10000</LogonCount>
            </AutoLogon>

The purpose of post_inst_cmd is to download the script for further actions from http://@@http_server@@/cblr/svc/op/autoinstall/profile/@@profile_name@@. To do this, the name of the profile is passed to it as a parameter.

post_inst_cmd.template example:

%systemdrive%
CD %systemdrive%\TMP >nul 2>&1

:wno10
set n=0

:wno20
ping @@http_server@@ -n 3
set exit_code=%ERRORLEVEL%

IF %exit_code% EQU 0 GOTO wno_exit
set /a n=n+1
IF %n% lss 30 goto wno20
pause
goto wno10

:wno_exit

wget.exe http://@@http_server@@/cblr/svc/op/autoinstall/profile/%1
MOVE %1 install.cmd
todos.exe install.cmd
start /wait install.cmd
DEL /F /Q libeay32.dll >nul 2>&1
DEL /F /Q libiconv2.dll >nul 2>&1
DEL /F /Q libintl3.dll >nul 2>&1
DEL /F /Q libssl32.dll >nul 2>&1
DEL /F /Q wget.exe >nul 2>&1
DEL /F /Q %0 >nul 2>&1

As can be seen from the text of the script, for its successful execution you must have wget.exe and todos.exe.
To do this, we place them in /var/lib/tftpboot/winos/Win10_EN-x64/sources/$OEM$/$1/TMP:

# ls '/var/lib/tftpboot/winos/Win10_EN-x64/sources/$OEM$/$1/TMP'
libeay32.dll  libiconv2.dll  libintl3.dll  libssl32.dll  sleep.exe  todos.exe  wget.exe

/var/lib/cobbler/templates/win.ks - plays the role of the %post section of RedHat kickstart. It can contain any commands executed in the Windows command line.

/var/lib/tftpboot/winos/winpe8.template - we have already prepared earlier. This WinPe image is used for Windows 8 and newer versions.
Trigger sync_post_wingen.py copies it to the distribution directory and replaces the startnet.cmd script in the copy.
Copying is done as reflink if possible (cp --reflink=auto)

  1. Boot menu
    Cobbler 3.2 does not support building the correct boot menu for Windows profiles. Therefore, we create them with the --enable-menu=False option and create the boot menu manually by placing the necessary items in /etc/cobbler/boot_loader_conf/pxedefault.template:
--- pxedefault.template.orig
+++ pxedefault.template
@@ -12,4 +12,8 @@
 
 $pxe_menu_items
 
+label Win10_EN-x64
+        MENU INDENT 5
+        MENU LABEL Win10_EN-x64
+        kernel /winos/Win10_EN-x64/win10a.0
 MENU end
  1. Distro and profiles
# cobbler distro add --name=Win10_EN-x64 --kernel=/var/lib/tftpboot/winos/Win10_EN-x64/pxeboot.n12 \
--initrd=/var/lib/tftpboot/winos/Win10_EN-x64/boot/boot.sdi --boot-loader=pxelinux --arch=x86_64 \
--breed=windows --os-version=10 \
--kernel-options='post_install=/var/lib/tftpboot/winos/Win10_EN-x64/sources/$OEM$/$1/post_install.cmd'

# cobbler distro report --name=Win10_EN-x64
Name                           : Win10_EN-x64
Architecture                   : x86_64
Automatic Installation Template Metadata : {}
TFTP Boot Files                : {}
Boot loader                    : pxelinux
Breed                          : windows
Comment                        : 
Fetchable Files                : {}
Initrd                         : /var/lib/tftpboot/winos/Win10_EN-x64/boot/boot.sdi
Kernel                         : /var/lib/tftpboot/winos/Win10_EN-x64/pxeboot.n12
Kernel Options                 : {'post_install': '/var/lib/tftpboot/winos/Win10_EN-x64/sources/$OEM$/$1/post_install.cmd'}
Kernel Options (Post Install)  : {}
Management Classes             : []
OS Version                     : 10
Owners                         : ['admin']
Redhat Management Key          : 
Remote Boot Initrd             : ~
Remote Boot Kernel             : ~
Template Files                 : {}

# cobbler profile add --name=Win10_EN-x64 --distro=Win10_EN-x64 --enable-menu=False --autoinstall=win.ks \
--kernel-options='pxeboot=win10a.0 bootmgr=boot1ea.exe bcd=1Ea winpe=winpe.wim sif=autounattended.xml'

# cobbler profile report --name=Win10_EN-x64
Name                           : Win10_EN-x64
Automatic Installation Template : win.ks
Automatic Installation Metadata : {}
TFTP Boot Files                : {}
Comment                        : 
DHCP Tag                       : default
Distribution                   : Win10_EN-x64
Enable gPXE?                   : False
Enable PXE Menu?               : False
Fetchable Files                : {}
DHCP Filename Override         : <<inherit>>
Kernel Options                 : {'pxeboot': 'win10a.0', 'bootmgr': 'boot1ea.exe', 'bcd': '1Ea', 'winpe': 'winpe.wim', 'sif': 'autounattended.xml'}
Kernel Options (Post Install)  : {}
Management Classes             : []
Management Parameters          : <<inherit>>
Name Servers                   : []
Name Servers Search Path       : []
Next Server Override           : <<inherit>>
Owners                         : ['admin']
Parent Profile                 : 
Proxy                          : 
Red Hat Management Key         : <<inherit>>
Repos                          : []
Server Override                : <<inherit>>
Template Files                 : {}
Virt Auto Boot                 : True
Virt Bridge                    : xenbr0
Virt CPUs                      : 1
Virt Disk Driver Type          : raw
Virt File Size(GB)             : 5
Virt Path                      : 
Virt RAM (MB)                  : 512
Virt Type                      : xenpv

# cobbler sync
< .. >
running python trigger cobbler.modules.sync_post_wingen

Windows profiles:
Profile: Win10_EN-x64
Build answer file: /var/lib/tftpboot/winos/Win10_EN-x64/sources/autounattended.xml
Build PXEBoot: /var/lib/tftpboot/winos/Win10_EN-x64/win10a.0
Build Loader: /var/lib/tftpboot/winos/Win10_EN-x64/boot1ea.exe
Build BCD: /var/lib/tftpboot/winos/Win10_EN-x64/boot/1Ea for /winos/Win10_EN-x64/boot/winpe.wim
running: /usr/bin/cp --reflink=auto /var/lib/tftpboot/winos/winpe8.template /var/lib/tftpboot/winos/Win10_EN-x64/boot/winpe.wim
received on stdout: 
received on stderr: 
running: /usr/bin/wimupdate /var/lib/tftpboot/winos/Win10_EN-x64/boot/winpe.wim --command="add /tmp/tmph981kc7w /Windows/System32/startnet.cmd"
received on stdout: Scanning "/tmp/tmph981kc7w" (loading as WIM path: "/Windows/System32/startnet.cmd")...
  1. Create a virtual machine, for example with virt-manager
    Снимок экрана от 2023-08-29 12-57-42
    Снимок экрана от 2023-08-29 12-58-42
    Снимок экрана от 2023-08-29 12-58-54
    Снимок экрана от 2023-08-29 12-59-12

  2. Start the virtual machine, select Win10_EN-x64 in the cobbler boot menu and wait for the installation to complete.
    Снимок экрана от 2023-08-29 17-49-06
    Снимок экрана от 2023-08-29 17-49-59
    Снимок экрана от 2023-08-29 18-06-16

from cobbler.

tpw56j avatar tpw56j commented on June 11, 2024 1

Hello, @Ankele

If we are talking about version 3.3.3, then /etc/cobbler/windows/answerfile.template is only an example of what a template for creating a Windows answer file might look like.
The actual template is created to meet the specific requirements of a Windows installation. The complete answerfile syntax can be found at https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend. Using this documentation, you can create your own answerfile template for the most common use cases. Then, to take into account the specifics of the Windows version, you can use the capabilities of cobbler, for example::

            <ImageInstall>
                <OSImage>
                    <InstallFrom>
                        <Credentials>
                            <Domain></Domain>
                        </Credentials>
                        <MetaData wcm:action="add">
                            <Key>/IMAGE/NAME</Key>
#if $os_version == '10'
                            <Value>Windows 10 Enterprise 2016 LTSB</Value>
#else if $os_version == '2016'
                            <Value>Windows Server 2016 SERVERSTANDARD</Value>
#else if $os_version == '2019'
                            <Value>Windows Server 2019 SERVERSTANDARD</Value>
#end if

Next, you can add additional metadata to the --autoinstall-meta for profiles for non-standard cases and add the corresponding elements to answerfile.template:

        </component>
        <component name="Microsoft-Windows-Setup" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
#if "clean_disk"  in $autoinstall_meta
            <DiskConfiguration>
                <WillShowUI>OnError</WillShowUI>
                <Disk wcm:action="add">
                    <DiskID>0</DiskID>
                    <WillWipeDisk>true</WillWipeDisk>
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Order>1</Order>
                            <Extend>true</Extend>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                </Disk>
            </DiskConfiguration>
#end if

When creating your answerfile, you should follow Microsoft's recommendations: https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/wsim/best-practices-for-authoring-answer-files?source=recommendations
Including after the cobbler sync command, validate the resulting answerfile /var/www/cobbler/images/win10-x86_64/autounattended.xml by loading it into Windows SIM:
Снимок экрана от 2023-09-12 09-37-35

After fixing the errors, make the appropriate changes to answerfile.template, run cobbler sync and start the installation again.

from cobbler.

SchoolGuy avatar SchoolGuy commented on June 11, 2024

@tpw56j is the expert for Windows. As such I would love him to step in as soon as his time allows. For now my focus must be to finish 3.4.0.

from cobbler.

tpw56j avatar tpw56j commented on June 11, 2024

@brook-w Could you point out the steps that require further explanation?

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

I tried to install windows using the official website, but it didn't work successfully. I tried win10 and win2019, but it didn't work.
But I use cobbler 2.8.5 it works fine

from cobbler.

tpw56j avatar tpw56j commented on June 11, 2024

Unfortunately, cobbler 2.8.5 is not well suited for windows installation, although it is still possible by manually preparing many files and doing some of the work in a windows environment.
More convenient preparation is implemented in cobbler 3.3.1, where support for importing a windows distribution has appeared. But full automation of windows installation preparation is not yet available in this version either. In particular, you need to manually prepare the samba share (smb.conf) and the translation rules for tftp (tftp.rules) as it is said in: https://github.com/cobbler/cobbler/blob/main/docs/user-guide/wingen.rst

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

I've tried this tutorial several times, including my colleagues, with no success, 2.8.5 requires manual steps but it works flawlessly, so we'd like a full tutorial or a full deployment blog, though I know it's a little irrational, but we do have this problem

Thank you !!!

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

Our environment is centos8
3.2.2 and 3.3 (no cobbler web) deployed respectively
and centos7 2.8.5 (works perfectly, lots of manual steps and old python interpreter,this is why we want to upgrade to 3.x)

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

At present, we have searched for some information on search engines, but we can only find very few cobbler 3.wndows installation content, and most of the content is official documents, so it is best to have a supplementary blog or deployment tutorial

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

Thank you, I'll try and feedback

from cobbler.

tpw56j avatar tpw56j commented on June 11, 2024

Another option for preparing a Windows installation that is much easier.

Sources for installation:

  1. CentOS-Stream-9-latest-x86_64-dvd1.iso from https://www.centos.org/download
  2. Win10_22H2_English_x64v1.iso from https://www.microsoft.com/software-download/windows10
  3. wimboot from https://github.com/ipxe/wimboot/releases/latest/download/wimboot

Purpose: to install Windows 10 in a KVM virtual machine (UEFI Boot).

Step by step:

  1. Install CentOS 9 with Server + GIU
  2. In my test environment, I can disable selinux and firewall
# setenforce 0
# systemctl stop firewalld
  1. Installing additional repos and packages
# dnf -y install epel-release
# dnf -y --enablerepo=crb install cobbler python3-pefile python3-hivex wimlib-utils \
   libvirt virt-manager ipxe-bootimgs-x86 samba
  1. Prepare tftp
# systemctl enable --now tftp
  1. Cobbler settings and patches
# ifconfig virbr0
virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.124.1  netmask 255.255.255.0  broadcast 192.168.124.255
        ether 52:54:00:d5:fd:c1  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
--- /etc/cobbler/settings.yaml.orig
+++ /etc/cobblersettings.yaml
@@ -324,7 +324,7 @@
 # if using Cobbler with manage_dhcp, put the IP address
 # of the Cobbler server here so that PXE booting guests can find it
 # if you do not set this correctly, this will be manifested in TFTP open timeouts.
-next_server_v4: 127.0.0.1
+next_server_v4: 192.168.124.1
 
 # And the same if you set manage_dhcp_v6 to true.
 # Set the cobbler IPv6 address here so that PXE booting guests can find it
@@ -460,7 +460,7 @@
 # if you have a server that appears differently to different subnets
 # (dual homed, etc), you need to read the --server-override section
 # of the manpage for how that works.
-server: 127.0.0.1
+server: 192.168.124.1
 
 # If set to true, all commands will be forced to use the localhost address
 # instead of using the above value which can force commands like
--- /etc/cobbler/settings.d/windows.settings.orig
+++ /etc/cobbler/settings.d/windows.settings
@@ -1,5 +1,5 @@
 # Set to true to enable the generation of Windows boot files in Cobbler.
-windows_enabled: false
+windows_enabled: true
 
 # Location of templates used for Windows
 windows_template_dir: "/etc/cobbler/windows"

Cobbler has an issue initrd=initrd.magic in /etc/cobbler/boot_loader_conf/ipxe.template #3475
I suggest just removing initrd=initrd.magic from the template:

--- /etc/cobbler/boot_loader_conf/ipxe.template.orig
+++ /etc/cobbler/boot_loader_conf/ipxe.template
@@ -14,7 +14,7 @@
 iseq \${smbios/manufacturer} HP && exit ||
 sanboot --no-describe --drive 0x80
 #else
-kernel $kernel_path $kernel_options initrd=initrd.magic
+kernel $kernel_path $kernel_options
 #for $init in $initrd
 initrd $init
 #end for

There is also a problem with Winows UEFI, so you need to fix it from #3477 .

--- sync_/usr/lib/python3.9/site-packages/cobbler/modules/post_wingen.py.orig
+++ /usr/lib/python3.9/site-packages/cobbler/modules/sync_post_wingen.py
@@ -80,8 +80,10 @@
 
     b = h.node_add_child(objs, "{65c31250-afa2-11df-8045-000c29f37d88}")
     d = h.node_add_child(b, "Description")
-    h.node_set_value(d, {"key": "Type", "t": REG_DWORD, "value": b"\x03\x00\x20\x13"})
+    h.node_set_value(d, {"key": "Type", "t": REG_DWORD, "value": b"\x03\x00\x20\x10"})
     e = h.node_add_child(b, "Elements")
+    e1 = h.node_add_child(e, "12000002")
+    h.node_set_value(e1, {"key": "Element", "t": REG_SZ, "value": "\\windows\\system32\\winload.exe\0".encode(encoding="utf-16le"), }, )
     e1 = h.node_add_child(e, "12000004")
     h.node_set_value(e1, {"key": "Element", "t": REG_SZ, "value": "Windows PE\0".encode(encoding="utf-16le")})
     e1 = h.node_add_child(e, "22000002")
@@ -172,9 +174,6 @@
         is_wimboot = "wimboot" in kernel_name
 
         if is_wimboot:
-            distro_path = os.path.join(settings.webdir, "distro_mirror", distro.name)
-            kernel_path = os.path.join(distro_path, "boot")
-
             if "kernel" in meta and "wimboot" not in distro.kernel:
                 tgen.copy_single_distro_file(os.path.join(settings.tftpboot_location, kernel_name), distro_dir, False)
                 tgen.copy_single_distro_file(os.path.join(distro_dir, kernel_name), web_dir, True)
@@ -296,7 +295,7 @@
                 wim_file_name = meta["winpe"]
 
             if is_wimboot:
-                wim_file_name = '\\Boot\\' + wim_file_name
+                wim_file_name = "\\Boot\\" + "winpe.wim"
                 sdi_file_name = '\\Boot\\' + 'boot.sdi'
             else:
                 wim_file_name = os.path.join("/images", distro.name, wim_file_name)
# systemctl enable --now httpd
# systemctl enable --now cobblerd

# cobbler version
Cobbler 3.3.3
  source: ?, ?
  build time: Tue Jun 14 00:00:00 2022
  1. Prepare libvirt default network for network iPXE boot
# systemctl enable --now libvirtd
# virsh net-destroy default
Network default destroyed

Change default network as follows:

# virsh net-edit default
--- default.xml.orig
+++ default.xml
@@ -1,4 +1,4 @@
-<network>
+<network xmlns:dnsmasq='http://libvirt.org/schemas/network/dnsmasq/1.0'>
   <name>default</name>
   <uuid>017d86e8-510a-4f1f-ad0d-18ae528436bd</uuid>
   <forward mode='nat'/>
@@ -9,5 +9,13 @@
       <range start='192.168.124.2' end='192.168.124.254'/>
     </dhcp>
   </ip>
+  <dnsmasq:options>
+    <dnsmasq:option value='dhcp-match=set:efi-x86_64,option:client-arch,7'/>
+    <dnsmasq:option value='dhcp-boot=tag:efi-x86_64,ipxe-x86_64.efi'/>
+    <dnsmasq:option value='dhcp-match=set:ipxe,175'/>
+    <dnsmasq:option value='dhcp-boot=tag:ipxe,/ipxe/default.ipxe'/>
+    <dnsmasq:option value='dhcp-match=set:bios,option:client-arch,0'/>
+    <dnsmasq:option value='dhcp-boot=tag:bios,pxelinux.0'/>
+  </dnsmasq:options>
 </network>
# virsh net-start default
Network default started
# cp wimboot /var/lib/tftpboot
# cp /usr/share/ipxe/ipxe-x86_64.efi /var/lib/tftpboot
  1. Prepare Windows distro
# mount -o loop,ro Win10_22H2_English_x64v1.iso /mnt
# cobbler import --path=/mnt --name=win10
# cobbler profile edit --name=win10-x86_64 \
  --autoinstall-meta="kernel=http://@@http_server@@/cobbler/images/@@distro_name@@/wimboot bootmgr=bootmgr.exe bcd=bcd winpe=winpe.wim answerfile=autounattended.xml"
# cobbler sync

Cobbler expects to find the Windows distro in /var/www/cobbler/distro_mirror/win10-x86_64, so:

# cd /var/www/cobbler/distro_mirror
# ln -s win10 win10-x86_64
# ls -l
drwxr-xr-x 2 root   root   4096 Sep 22  2022 config
dr-xr-xr-x 6 nobody nobody 4096 Sep  6 17:10 win10
lrwxrwxrwx 1 root   root      5 Sep  6 17:37 win10-x86_64 -> win10
  1. Samba share

Add the following lines to the end of /etc/samba/smb.conf:

[DISTRO]
	comment = Windows distributions
	path = /var/www/cobbler/distro_mirror
	guest ok = yes
	browseable = yes
	public = yes
	writeable = no
	printable = no
	locking = no
# systemctl enable --now smb
  1. Create and start VM

When creating a VM, specify Firmware UEFI x86_64: /usr/share/edk2/ovmf/OVMF_CODE.fd

Снимок экрана от 2023-09-06 17-19-23

Start VM

Снимок экрана от 2023-09-06 17-23-49
Снимок экрана от 2023-09-06 17-24-16
Снимок экрана от 2023-09-06 17-28-35

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

Thank you, I'll try and feedback
I will follow your steps and execute it once
I will give up again until the complete installation is successful. After that, I will have a complete installation tutorial for others to use

from cobbler.

Ankele avatar Ankele commented on June 11, 2024

hello, @tpw56j
Follow your steps to deploy windows10 and windows2019,I got an error "could not apply unattended settings during [offlineServicing]",hope to get your help

from cobbler.

Ankele avatar Ankele commented on June 11, 2024

@tpw56j Can I get your complete autounattended.xml ? I think that would be very helpful for me,

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

@tpw56j
(Previously used: win2019 cobbler 2.8.5 use success autounattended.xml )
windows-could-not-apply-unattended-settings-during-pass-offlineservicing error
It seems that it is really not possible. I tried to use Win10 EN/Win10 ZH to choose a mirror image that can be installed on the selection of the mirror page.
Then I tried Win Server 2019. They did not have the problem of win10 EN/ZH, but the problem of disk options occurred. I refer to the Microsoft's official documentation and add the partition. The installation is updated (the fourth step of the installation step)

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

Is it possible that there are some problems in the automatic file, or you can share your autounattended.xml
Or supplement the previous installation tutorial, because seeing the previous screenshot, it was launched after loading TFTP and HTTP files, and I didn’t see the complete installation process.
Hope to see the complete installation process #3473 (comment)
image

Thank you!!!

from cobbler.

tpw56j avatar tpw56j commented on June 11, 2024

@Ankele
@brook-w
With my autounattended.xml, I also received the error “could not apply unattended settings during [offlineServicing]” when installing Win 10 22H2. Although installation 10 (1809) is successful. Very similar to https://www.tenforums.com/tutorials/96683-create-media-automated-unattended-install-windows-10-a-83.html. But the solution that worked there does not work in our case.
This is most likely a Windows bug. And although this is not a cobbler problem, I will nevertheless try to look for a solution.

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

@tpw56j

Although installation 10 (1809) is successful

For this successful installation experiment, can you share your autounattended.xml file and mirror download address?
I want to engage in your experiments one to a time
Thank you!

from cobbler.

Ankele avatar Ankele commented on June 11, 2024

hello @tpw56j
I got some new error while I install windows2019 in cobbler3.3.3 manually.
the following pictures are my steps:

  1. stop automatical batches and use manual operation
    image

image
3.
image
4.
image
image
5. finally, the installatiohn was canceled
image

and I try some other operation systems such as cn-windows-2019-1809, cn-windows10-1809 and en-windows10-1809, all of them occur the same errors, all the images are downloaded from microsoft.
I guess this error is likely caused by winpe.wim generated by cobbler.

I hope to get your help.

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

@tpw56j Please help us

from cobbler.

tpw56j avatar tpw56j commented on June 11, 2024

@Ankele You are right, the problem is winpe.wim.
Cobbler changes Microsoft\Windows NT\CurrentVersion\SystemRoot from X:\$windows.~bt\Windows to X:\Windows in its /Windows/System32/config/SOFTWARE registry and deletes Microsoft\Windows NT\CurrentVersion\WinPE\InstRoot.
This is a hack that in very old versions of WinPE made it possible to do without dism.exe.

In new versions of WinPE, the hack no longer works and the "cobbler import" command breaks winpe.wim. I have not yet found a solution to this problem and can only offer this workaround:

  1. take any WinPE image, or from Windows AIK, or execute wimexport boot.wim 1 winpe.wim.
  2. On Windows with AIK installed, run the commands:
C:\WinPE_amd64>dism /mount-wim /wimfile:winpe.wim /index:1 /mountdir:mount
C:\WinPE_amd64>dism /image:mount /set-targetpath:X:\
C:\WinPE_amd64>dism /unmount-wim  /mountdir:mount /commit
  1. Replace the file /var/www/cobbler/distro_mirror/win10/boot/winpe.wim.
  2. cobbler sync

I checked the winpe.wim prepared by the "cobbler import" command using dism and it returned the correct value, but winpe.wim still remains broken.

C:\WinPE_amd64>dism /image:mount /get-targetpath

Deployment Image Servicing and Management tool
Version: 10.0.22621.1

Image Version: 10.0.19041.2965

Target path to the root of the Windows PE image at boot time:
Target Path : X:\

The operation completed successfully.

I also tried to find what the dism /set-targetpath command changes in the registry, but it turned out that there are a lot of changes and I don’t know which of them are key to creating the correct winpe.wim.

@brook-w My autounattended.xml file is the same as https://github.com/cobbler/cobbler/blob/release33/templates/windows/answerfile.template, but for EFI installation I made changes to the disk partitions:

        <component name="Microsoft-Windows-Setup" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DiskConfiguration>
                <WillShowUI>OnError</WillShowUI>
                <Disk wcm:action="add">
                    <DiskID>0</DiskID>
                    <WillWipeDisk>true</WillWipeDisk>
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Order>1</Order>
                            <Type>Primary</Type>
                            <Size>300</Size>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>2</Order>
                            <Type>EFI</Type>
                            <Size>100</Size>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>3</Order>
                            <Type>MSR</Type>
                            <Size>128</Size>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>4</Order>
                            <Extend>true</Extend>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                </Disk>
            </DiskConfiguration>
            <ImageInstall>
                <OSImage>
                    <InstallFrom>
                        <Credentials>
                            <Domain></Domain>
                        </Credentials>
                        <MetaData wcm:action="add">
                            <Key>/IMAGE/NAME</Key>
#if $profile_name == 'IOS'
                            <Value>Windows8_VmVare_MacOS_xCode</Value>
#else if $os_version == '7'
                            <Value>Windows 7 PROFESSIONAL</Value>
#else if $os_version == '8'
                            <Value>Windows 8.1 Pro</Value>
#else if $os_version == '10'
                            <Value>Windows 10 Pro</Value>
#else if $os_version == '2008'
                            <Value>Windows Server 2008 R2 SERVERENTERPRISE</Value>
#else if $os_version == '2012'
                            <Value>Windows Server 2012 R2 SERVERDATACENTER</Value>
#else if $os_version == '2016'
                            <Value>Windows Server 2016 SERVERSTANDARD</Value>
#else if $os_version == '2019'
                            <Value>Windows Server 2019 SERVERSTANDARD</Value>
#end if
                        </MetaData>
                    </InstallFrom>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>4</PartitionID>
                    </InstallTo>
                </OSImage>
            </ImageInstall>
            <UserData>
                <ProductKey>
#if $os_version == '10'
                    <Key>W269N-WFGWX-YVC9B-4J6C9-T83GX</Key>
#else if $os_version == '2012'
                    <Key>Y4TGP-NPTV9-HTC2H-7MGQ3-DV4TW</Key>
#end if
                    <WillShowUI>Never</WillShowUI>
                </ProductKey>
                <AcceptEula>true</AcceptEula>
                <FullName>DEMO</FullName>
                <Organization>DEMO</Organization>
            </UserData>
            <EnableFirewall>false</EnableFirewall>
        </component>

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

@tpw56j
In version 2.8.5, we are the manual winpe.wim,but there are some differences between the process and the way you
@Ankele and I thank you!
We will continue to try your plan and give you feedback
disk partitions problem we have solved
I hope you can tell us when you have a new solution. Thank you very much. My team also thank you

from cobbler.

brook-w avatar brook-w commented on June 11, 2024

@tpw56j We are successful
My Env:

  • Cobbler 3.3
  • cn_windows_server_2019_updated_jan_2020_x64_dvd_4bbe2c37.iso
  • Rocky 9.1
    We used winpe.wim in the AIK 2019 toolkit to replace the winpe.wim generated by cobbler import
    The specific step is like this:
  1. pre
cobbler import --path /iso/win2019 --name win2019
  1. get AIK winpe.wim (Install the environment in advance)
C:\Program Files (x86)\Windows Kits\2019\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\en-us\winpe.wim
  1. use AIK winpe.wim replace /var/www/cobbler/images/win2019/winpe.wim
  2. write smaba and autoinstall to winpe.wim
cat /root/2019_autoinstall

wpeinit

ping 127.0.0.1 -n 10 >nul
net use z: \\192.168.1.221\DISTRO\win2019-x86_64
set exit_code=%ERRORLEVEL%
IF %exit_code% EQU 0 GOTO INSTALL
echo "Can't mount network drive"
pause
goto EXIT

:INSTALL

z:\sources\setup.exe /unattend:Z:\autounattended.xml
:EXIT
exit


/usr/bin/wimupdate /var/www/cobbler/images/win2019-x86_64/winpe.wim --command="add /root/2019_autoinstall /Windows/System32/startnet.cmd"
  1. execute installation ===> success!!!

from cobbler.

tpw56j avatar tpw56j commented on June 11, 2024

@brook-w
@Ankele
I think I found a solution to the problem with offlineServicing after "cobbler import".
In new versions of WinPE, the string "X:\$windows.~bt" appears not only in the "SystemRoot" value, but also in many other registry keys and values. After I replaced them all, I was able to successfully complete the installation.

Could you please test the solution bbc815d?

# cobbler import --path=/mnt --name=win10
# cd /var/www/cobbler/distro_mirror
# ln -s win10 win10-x86_64
# cobbler profile edit --name=win10-x86_64 \
  --autoinstall-meta="kernel=http://@@http_server@@/cobbler/images/@@distro_name@@/wimboot bootmgr=bootmgr.exe bcd=bcd winpe=winpe.wim answerfile=autounattended.xml"
# cobbler sync

from cobbler.

tpw56j avatar tpw56j commented on June 11, 2024

Fully unattended installation Windows 11

Sources for installation:

Purpose: to install Windows 11 in a KVM virtual machine (UEFI Secure Boot).

  1. Install CentOS 9 with Server + GIU
  2. In my test environment, I can disable selinux and firewall
# setenforce 0
# systemctl stop firewalld
  1. Installing additional repos and packages
# dnf -y install epel-release
# dnf -y --enablerepo=crb install cobbler python3-pefile python3-hivex wimlib-utils \
   libvirt virt-manager ipxe-bootimgs-x86 samba  python3-virt-firmware
# dnf -y install https://kojipkgs.fedoraproject.org//packages/sbsigntools/0.9.5/1.fc38/x86_64/sbsigntools-0.9.5-1.fc38.x86_64.rpm
  1. Cobbler settings and patches
# ifconfig virbr0
virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.124.1  netmask 255.255.255.0  broadcast 192.168.124.255
        ether 52:54:00:d5:fd:c1  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
--- /etc/cobbler/settings.yaml.orig
+++ /etc/cobblersettings.yaml
@@ -324,7 +324,7 @@
 # if using Cobbler with manage_dhcp, put the IP address
 # of the Cobbler server here so that PXE booting guests can find it
 # if you do not set this correctly, this will be manifested in TFTP open timeouts.
-next_server_v4: 127.0.0.1
+next_server_v4: 192.168.124.1
 
 # And the same if you set manage_dhcp_v6 to true.
 # Set the cobbler IPv6 address here so that PXE booting guests can find it
@@ -460,7 +460,7 @@
 # if you have a server that appears differently to different subnets
 # (dual homed, etc), you need to read the --server-override section
 # of the manpage for how that works.
-server: 127.0.0.1
+server: 192.168.124.1
 
 # If set to true, all commands will be forced to use the localhost address
 # instead of using the above value which can force commands like
--- /etc/cobbler/settings.d/windows.settings.orig
+++ /etc/cobbler/settings.d/windows.settings
@@ -1,5 +1,5 @@
 # Set to true to enable the generation of Windows boot files in Cobbler.
-windows_enabled: false
+windows_enabled: true
 
 # Location of templates used for Windows
 windows_template_dir: "/etc/cobbler/windows"

Cobbler has an issue initrd=initrd.magic in /etc/cobbler/boot_loader_conf/ipxe.template #3475
I suggest just removing initrd=initrd.magic from the template:

--- /etc/cobbler/boot_loader_conf/ipxe.template.orig
+++ /etc/cobbler/boot_loader_conf/ipxe.template
@@ -14,7 +14,7 @@
 iseq \${smbios/manufacturer} HP && exit ||
 sanboot --no-describe --drive 0x80
 #else
-kernel $kernel_path $kernel_options initrd=initrd.magic
+kernel $kernel_path $kernel_options
 #for $init in $initrd
 initrd $init
 #end for

My /etc/cobbler/windows/answerfile.template:

#if $arch == 'x86_64'
        #set $win_arch = 'amd64'
#else if $arch == 'i386'
        #set $win_arch = 'i386'
#end if
#if $os_version not in ('xp', '2003')
#set $procarch = 'processorArchitecture="' + $win_arch + '"'
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SetupUILanguage>
#if "locale" in $autoinstall_meta
                <UILanguage>@@locale@@</UILanguage>
#else
                <UILanguage>en-US</UILanguage>
#end if
            </SetupUILanguage>
#if "locale" in $autoinstall_meta
            <InputLocale>@@locale@@</InputLocale>
            <SystemLocale>@@locale@@</SystemLocale>
            <UILanguage>@@locale@@</UILanguage>
            <UILanguageFallback>@@locale@@</UILanguageFallback>
            <UserLocale>@@locale@@</UserLocale>
#else
            <InputLocale>en-US</InputLocale>
            <SystemLocale>en-US</SystemLocale>
            <UILanguage>en-US</UILanguage>
            <UILanguageFallback>en-US</UILanguageFallback>
            <UserLocale>en-US</UserLocale>
#end if
        </component>
        <component name="Microsoft-Windows-Setup" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DiskConfiguration>
                <WillShowUI>OnError</WillShowUI>
                <Disk wcm:action="add">
                    <DiskID>0</DiskID>
                    <WillWipeDisk>true</WillWipeDisk>
#set $part_num = 0
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
#set $part_num += 1
                            <Order>$part_num</Order>
                            <Type>Primary</Type>
                            <Size>300</Size>
#if $os_version not in ('7')
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
#set $part_num += 1
                            <Order>$part_num</Order>
                            <Type>EFI</Type>
                            <Size>100</Size>
                        </CreatePartition>
#end if
                        <CreatePartition wcm:action="add">
#set $part_num += 1
                            <Order>$part_num</Order>
                            <Type>MSR</Type>
                            <Size>128</Size>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
#set $part_num += 1
                            <Order>$part_num</Order>
                            <Extend>true</Extend>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                </Disk>
            </DiskConfiguration>
            <ImageInstall>
                <OSImage>
                    <InstallFrom>
                        <Credentials>
                            <Domain></Domain>
                        </Credentials>
                        <MetaData wcm:action="add">
                            <Key>/IMAGE/NAME</Key>
#if $profile_name == 'IOS'
                            <Value>Windows8_VmVare_MacOS_xCode</Value>
#else if $os_version == '7'
                            <Value>Windows 7 PROFESSIONAL</Value>
#else if $os_version == '8'
                            <Value>Windows 8.1 Pro</Value>
#else if $os_version == '10'
                            <Value>Windows 10 Pro</Value>
#else if $os_version == '11'
                            <Value>Windows 11 Pro</Value>
#else if $os_version == '2008'
                            <Value>Windows Server 2008 R2 SERVERENTERPRISE</Value>
#else if $os_version == '2012'
                            <Value>Windows Server 2012 R2 SERVERDATACENTER</Value>
#else if $os_version == '2016'
                            <Value>Windows Server 2016 SERVERSTANDARD</Value>
#else if $os_version == '2019'
                            <Value>Windows Server 2019 SERVERSTANDARD</Value>
#end if
                        </MetaData>
                    </InstallFrom>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>$part_num</PartitionID>
                    </InstallTo>
                </OSImage>
            </ImageInstall>
            <UserData>
                <ProductKey>
#if $os_version == '10'
                    <Key>W269N-WFGWX-YVC9B-4J6C9-T83GX</Key>
#else if $os_version == '11'
                    <Key>W269N-WFGWX-YVC9B-4J6C9-T83GX</Key>
#else if $os_version == '2012'
                    <Key>Y4TGP-NPTV9-HTC2H-7MGQ3-DV4TW</Key>
#end if
                    <WillShowUI>Never</WillShowUI>
                </ProductKey>
                <AcceptEula>true</AcceptEula>
                <FullName>User</FullName>
                <Organization>Some Organization</Organization>
            </UserData>
            <EnableFirewall>true</EnableFirewall>
        </component>
        <component name="Microsoft-Windows-PnpCustomizationsWinPE" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DriverPaths>
                <PathAndCredentials wcm:action="add" wcm:keyValue="6">
                    <Path>\\@@http_server@@\@@samba_distro_share@@\@@distro_name@@\Drivers\@@os_version@@</Path>
                </PathAndCredentials>
            </DriverPaths>
        </component>
    </settings>
    <settings pass="offlineServicing">
        <component name="Microsoft-Windows-LUA-Settings" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <EnableLUA>false</EnableLUA>
        </component>
    </settings>
    <settings pass="specialize">
        <component name="Microsoft-Windows-Shell-Setup" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ComputerName>*</ComputerName>
            <RegisteredOrganization>Some Organization</RegisteredOrganization>
            <RegisteredOwner>User</RegisteredOwner>
            <TimeZone>UTC</TimeZone>
        </component>
        <component name="Microsoft-Windows-UnattendedJoin" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <Identification>
                <JoinWorkgroup>WORKGROUP</JoinWorkgroup>
            </Identification>
        </component>
        <component name="Microsoft-Windows-TerminalServices-LocalSessionManager" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <fDenyTSConnections>false</fDenyTSConnections>
        </component>
        <component name="Networking-MPSSVC-Svc" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <FirewallGroups>
                <FirewallGroup wcm:action="add" wcm:keyValue="EnableRemoteDesktop">
                    <Active>true</Active>
                    <Group>Remote Desktop</Group>
                    <Profile>all</Profile>
                </FirewallGroup>
            </FirewallGroups>
        </component>
        <component name="Microsoft-Windows-TerminalServices-RDP-WinStationExtensions" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <UserAuthentication>0</UserAuthentication>
        </component>
    </settings>
    <settings pass="oobeSystem">
        <component name="Microsoft-Windows-International-Core" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
#if "locale" in $autoinstall_meta
            <InputLocale>@@locale@@</InputLocale>
            <SystemLocale>@@locale@@</SystemLocale>
            <UILanguage>@@locale@@</UILanguage>
            <UILanguageFallback>@@locale@@</UILanguageFallback>
            <UserLocale>@@locale@@</UserLocale>
#else
            <InputLocale>en-US</InputLocale>
            <SystemLocale>en-US</SystemLocale>
            <UILanguage>en-US</UILanguage>
            <UILanguageFallback>en-US</UILanguageFallback>
            <UserLocale>en-US</UserLocale>
#end if
        </component>
        <component name="Microsoft-Windows-Shell-Setup" $procarch publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <OOBE>
                <NetworkLocation>Work</NetworkLocation>
                <VMModeOptimizations>
                    <SkipAdministratorProfileRemoval>false</SkipAdministratorProfileRemoval>
                </VMModeOptimizations>
                <HideEULAPage>true</HideEULAPage>
                <HideLocalAccountScreen>true</HideLocalAccountScreen>
                <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
                <HideOnlineAccountScreens>true</HideOnlineAccountScreens>
                <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
                <ProtectYourPC>3</ProtectYourPC>
                <UnattendEnableRetailDemo>false</UnattendEnableRetailDemo>
                <SkipMachineOOBE>true</SkipMachineOOBE>
                <SkipUserOOBE>true</SkipUserOOBE>
            </OOBE>
            <UserAccounts>
                <AdministratorPassword>
                    <Value>User</Value>
                    <PlainText>true</PlainText>
                </AdministratorPassword>
                <LocalAccounts>
                    <LocalAccount wcm:action="add">
                        <Password>
                            <Value>User</Value>
                            <PlainText>true</PlainText>
                        </Password>
                        <Name>User</Name>
                        <Group>Administrators</Group>
                    </LocalAccount>
                </LocalAccounts>
            </UserAccounts>
            <TimeZone>UTC</TimeZone>
            <RegisteredOrganization>Some Organization</RegisteredOrganization>
            <RegisteredOwner>User</RegisteredOwner>
            <FirstLogonCommands>
                <SynchronousCommand wcm:action="add">
                    <RequiresUserInput>false</RequiresUserInput>
                    <Order>1</Order>
                    <CommandLine>cmd /C wmic useraccount where "name='User'" set PasswordExpires=FALSE</CommandLine>
                </SynchronousCommand>
                <SynchronousCommand wcm:action="add">
                    <RequiresUserInput>false</RequiresUserInput>
                    <Order>2</Order>
                    <CommandLine>c:\post_install.cmd @@profile_name@@</CommandLine>
                </SynchronousCommand>
            </FirstLogonCommands>
            <AutoLogon>
                <Password>
                    <Value>User</Value>
                    <PlainText>true</PlainText>
                </Password>
                <Enabled>true</Enabled>
                <Username>User</Username>
                <LogonCount>10000</LogonCount>
            </AutoLogon>
        </component>
    </settings>
</unattend>
#else
#set $OriSrc = '\\\\' + $http_server + '\\' + $samba_distro_share + '\\' + $initrd.split('/')[-3] + '\\' + $win_arch
#set $DevSrc = '\\Device\\LanmanRedirector\\' + $http_server + '\\' + $samba_distro_share + '\\' + $initrd.split('/')[-3]
[Data]
floppyless = "1"
msdosinitiated = "1"
; Needed for second stage
OriSrc="$OriSrc"
OriTyp="4"
LocalSourceOnCD=1
DisableAdminAccountOnDomainJoin=0
AutomaticUpdates="No"
Autopartition="0"
UnattendedInstall="Yes"

[SetupData]
OsLoadOptions = "/noguiboot /fastdetect"
; Needed for first stage
SetupSourceDevice = "$DevSrc"

[Unattended]
CrashDumpSetting=0
FactoryMode=No
UnattendMode=FullUnattended
UnattendSwitch="Yes"
OemPreinstall="Yes"
OemSkipEula="Yes"
Repartition=No
FileSystem=*
WaitForReboot="No"
NoWaitAfterTextMode=1
NoWaitAfterGUIMode=1
DriverSigningPolicy=Ignore
NonDriverSigningPolicy=Ignore
UpdateInstalledDrivers=Yes
TargetPath=\WINDOWS
OemPnPDriversPath=DRIVERS\@@os_version@@

#if $os_version == '2003'
[LicenseFilePrintData]
;AutoMode = PerSeat

#end if
[Display]
BitsPerPel=32
XResolution=1440
YResolution=900
Vrefresh=60

[WindowsFirewall]
;Profiles = WindowsFirewall.TurnOffFirewall

[WindowsFirewall.TurnOffFirewall]
;Mode = 0

[PCHealth]
;RA_AllowToGetHelp=0

[GuiRunOnce]
"%Systemdrive%\post_install.cmd @@profile_name@@"

[GuiUnattended]
;DetachedProgram = "%SystemDrive%\D\M.exe"
;Arguments = -y
AdminPassword=*
;TimeZone=145
OEMSkipRegional=1
OemSkipWelcome=1
#if $os_version != '2003'
AutoLogon = Yes
AutoLogonCount=1
#end if

[RemoteInstall]
#if "clean_disk" in $autoinstall_meta
Repartition=Yes
UseWholeDisk=Yes
#end if

[Components]
;msmsgs=Off
;msnexplr=Off
;zonegames=Off
;Paint=Off
#if $os_version == '2003'
; Iis_common=On
; Iis_inetmgr=On
ComPlusNetwork=On
; Iis_www=On
; Iis_asp=On
;IEHardenAdmin=Off
;IEHardenUser=Off
#end if

[TerminalServices]
AllowConnections=1

[UserData]
#if $os_version == '2003'
ProductKey="VD2BM-TP2KK-CBXDQ-7B7FQ-4M9V3"
#else
ProductKey="CB9YB-Q73J8-RKPMH-M2WFT-P4WQJ"
#end if
ComputerName=*
FullName="Admin"
OrgName="Microsoft"

[RegionalSettings]
LanguageGroup=1,2,3,4,5
SystemLocale=00000409
UserLocale=00000409
InputLocale=0409:00000409

[Shell]
CustomDefaultThemeFile="%WinDir%\Resources\Themes\Windows Classic.Theme"

[Networking]
InstallDefaultComponents="Yes"

[Identification]
JoinWorkgroup = WORKGROUP
;JoinDomain = WORKGROUP
;DoOldStyleDomainJoin = Yes

[params.MS_TCPIP]
DNSDomain=example.com
#end if

There is also a problem with Winows UEFI, so you need to fix it from #3477

# systemctl enable --now httpd
# systemctl enable --now cobblerd

# cobbler version
Cobbler 3.3.3
  source: ?, ?
  build time: Tue Jun 14 00:00:00 2022
  1. Prepare libvirt default network for network iPXE boot
# systemctl enable --now libvirtd
# virsh net-destroy default
Network default destroyed

Change default network as follows:

# virsh net-edit default
--- default.xml.orig
+++ default.xml
@@ -1,4 +1,4 @@
-<network>
+<network xmlns:dnsmasq='http://libvirt.org/schemas/network/dnsmasq/1.0'>
   <name>default</name>
   <uuid>017d86e8-510a-4f1f-ad0d-18ae528436bd</uuid>
   <forward mode='nat'/>
@@ -9,5 +9,13 @@
       <range start='192.168.124.2' end='192.168.124.254'/>
     </dhcp>
   </ip>
+  <dnsmasq:options>
+    <dnsmasq:option value='dhcp-match=set:efi-x86_64,option:client-arch,7'/>
+    <dnsmasq:option value='dhcp-boot=tag:efi-x86_64,shimx64.efi'/>
+    <dnsmasq:option value='dhcp-match=set:ipxe,175'/>
+    <dnsmasq:option value='dhcp-boot=tag:ipxe,/ipxe/default.ipxe'/>
+    <dnsmasq:option value='dhcp-match=set:bios,option:client-arch,0'/>
+    <dnsmasq:option value='dhcp-boot=tag:bios,pxelinux.0'/>
+  </dnsmasq:options>
 </network>
# virsh net-start default
Network default started
  1. Prepare Windows distro
# mount -o loop,ro Win11_22H2_English_x64v2.iso /mnt
# cobbler import --path=/mnt --name=win11
# cobbler profile edit --name=win11-x86_64 \
  --autoinstall-meta="kernel=http://@@http_server@@/cobbler/images/@@distro_name@@/wimboot bootmgr=bootmgr.exe bcd=bcd winpe=winpe.wim answerfile=autounattended.xml"
# cobbler sync
  1. Samba share
    Add the following lines to the end of /etc/samba/smb.conf:
[DISTRO]
	comment = Windows distributions
	path = /var/www/cobbler/distro_mirror
	guest ok = yes
	browseable = yes
	public = yes
	writeable = no
	printable = no
	locking = no
# systemctl enable --now smb
  1. Create VM
    Снимок экрана от 2023-09-22 08-41-44
    Снимок экрана от 2023-09-22 08-43-42
    Снимок экрана от 2023-09-22 08-45-13
    Снимок экрана от 2023-09-22 08-47-02

Click "Begin Installation" and them "Force Off"

Снимок экрана от 2023-09-22 08-49-20

  1. Prepare boot loaders
# cp wimboot /var/lib/tftpboot

Create Secure Boot keys

# ./mkkeys.sh
Enter a Common Name to embed in the keys: DEMO

We only need the keys PK.*, KEK.*, DB.* and myGUID.txt, so you can safely ignore the messages:

./mkkeys.sh: line 21: cert-to-efi-sig-list: command not found
# ls -l
total 1036
-rw-r--r-- 1 root root    777 Sep 22 08:37 DB.cer
-rw-r--r-- 1 root root   1107 Sep 22 08:37 DB.crt
-rw------- 1 root root   1704 Sep 22 08:37 DB.key
-rw-r--r-- 1 root root 950624 Feb 10  2023 ipxe-shimx64.efi
-rw-r--r-- 1 root root    779 Sep 22 08:37 KEK.cer
-rw-r--r-- 1 root root   1111 Sep 22 08:37 KEK.crt
-rw------- 1 root root   1704 Sep 22 08:37 KEK.key
-rwxr-xr-x 1 root root   1757 Feb 28  2021 mkkeys.sh
-rw-r--r-- 1 root root     37 Sep 22 08:37 myGUID.txt
-rw-r--r-- 1 root root      0 Sep 22 08:37 noPK.esl
-rw-r--r-- 1 root root    777 Sep 22 08:37 PK.cer
-rw-r--r-- 1 root root   1107 Sep 22 08:37 PK.crt
-rw------- 1 root root   1704 Sep 22 08:37 PK.key
-rw-r--r-- 1 root root  59776 Sep 22 09:00 wimboot

For some reason unknown to me, /usr/share/ipxe/ipxe-x86_64.efi is not suitable for Secure Boot, so download it from the official website:

# wget https://boot.ipxe.org/ipxe.iso
# mkdir /mnt/{cdrom,disk}
# mount -o loop,ro ipxe.iso /mnt/cdrom
# mount -o loop,ro /mnt/cdrom/esp.img /mnt/disk

Sign ipxe-shimx64.efi and ipxe-x86_64.efi:

# sbsign --key DB.key --cert DB.crt --output /var/lib/tftpboot/shimx64.efi ipxe-shimx64.efi
# sbsign --key DB.key --cert DB.crt --output /var/lib/tftpboot/ipxe.efi /mnt/disk/EFI/BOOT/BOOTX64.EFI

Replace the keys in nvram:

# export GUID=`cat myGUID.txt`
# virt-fw-vars \
  --input /usr/share/edk2/ovmf/OVMF_VARS.fd \
  --output /var/lib/libvirt/qemu/nvram/win11_VARS.fd \
--set-pk  ${GUID} PK.crt \
--add-kek ${GUID} KEK.crt \
--add-kek 77fa9abd-0359-4d32-bd60-28f4e78f784b /usr/lib/python3.9/site-packages/virt/firmware/certs/MicrosoftCorporationKEKCA2011.pem \
--add-db  ${GUID} DB.crt \
--add-db  77fa9abd-0359-4d32-bd60-28f4e78f784b /usr/lib/python3.9/site-packages/virt/firmware/certs/MicrosoftWindowsProductionPCA2011.pem \
--add-db  77fa9abd-0359-4d32-bd60-28f4e78f784b /usr/lib/python3.9/site-packages/virt/firmware/certs/MicrosoftCorporationUEFICA2011.pem
INFO: reading raw edk2 varstore from /usr/share/edk2/ovmf/OVMF_VARS.fd
INFO: var store range: 0x64 -> 0x40000
INFO: create variable PK
INFO: clear PK sigdb
INFO: add PK cert PK.crt
INFO: create variable KEK
INFO: add KEK cert KEK.crt
INFO: add KEK cert /usr/lib/python3.9/site-packages/virt/firmware/certs/MicrosoftCorporationKEKCA2011.pem
INFO: create variable db
INFO: add db cert DB.crt
INFO: add db cert /usr/lib/python3.9/site-packages/virt/firmware/certs/MicrosoftWindowsProductionPCA2011.pem
INFO: add db cert /usr/lib/python3.9/site-packages/virt/firmware/certs/MicrosoftCorporationUEFICA2011.pem
INFO: writing raw edk2 varstore to /var/lib/libvirt/qemu/nvram/win11_VARS.fd
  1. Prepare tftp
# systemctl enable --now tftp
  1. Start VM
    Снимок экрана от 2023-09-22 18-12-12
    Снимок экрана от 2023-09-22 18-13-16
    Снимок экрана от 2023-09-22 18-15-05
    Снимок экрана от 2023-09-22 18-16-26
    Снимок экрана от 2023-09-22 18-47-07
    Снимок экрана от 2023-09-22 18-47-14
    Снимок экрана от 2023-09-22 19-08-38
    Снимок экрана от 2023-09-22 19-10-24
    Снимок экрана от 2023-09-22 19-10-42
    Снимок экрана от 2023-09-22 19-12-54
    Снимок экрана от 2023-09-22 19-14-07

from cobbler.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.