145 - Install Windows directly from an ISO file using iPXE wimboot (MBR\UEFI + grub2\grub4dos)

This method allows you to directly boot from a number of different unmodified Windows Install 7/8/10 ISOs on a bootable USB drive AND then run Setup to install Windows to a system.

No files need to be extracted from the ISO - just copy the ISO file and boot!

    • Legacy, UEFI or PXE boot is supported.

    • The ISO is automatically mounted as a virtual drive so Setup can find and use the Install.wim\esd file.

    • 2GB or more RAM is required to be in the system (it may fail to work if not enough RAM is available).

  • The Windows Install ISO file does not need to be modified in any way.

I will describe here only the outline process so that you can see how it is done. Easy2Boot uses a similar (but not identical) process when MBR-booting.

Example grub2 menus are also provided (grub4dos only MBR boots, grub2 will MBR and UEFI32 and UEFI64 boot).

Process in outline:

    1. Add Windows Install ISO to a grub4dos or grub2 bootable USB drive

    2. Add a menu for grub4dos\grub2

    3. The menu uses wimboot to boot to files inside the ISO

    4. Add in a null.cfg file which contains the full path of the ISO (except for the drive letter)

    5. The menu also injects a startnet.bat file and winpeshl.ini file

    6. For MBR booting we swap BIOS device hd0 with hd1 so that Windows does not think the boot drive is the USB drive (it may refuse to install Windows to a Removable USB drive or Setup may install the Windows boot code to a USB hard disk if we don't do this).

    7. When the grub2\grub4dos menu is picked, here is what happens...

      1. The ISO is mounted (by grub4dos as a CD device using map or by grub2 as a loop device)

      2. wimboot will load the boot.wim, boot.SDI and BCD from the mounted ISO into RAM

      3. wimboot injects into the boot.wim\X: RAM drive a null.cfg file which contains the file path of the ISO

      4. wimboot injects into the boot.wim\X: RAM drive a winpeshl.ini and startup.bat file

      5. The boot.wim file is booted to by wimboot via bootmgr+BCD and startup.bat runs

      6. startup.bat finds the USB drive and installs ImDisk (which is also located in a folder on the USB drive somewhere)

      7. startup.bat finds the null.cfg file in X:\Windows\System32 and from this we can determine the name of the ISO that we need to load

      8. startup.bat uses ImDisk to load the ISO as drive Y: from the USB drive

      9. startup.bat runs X:\Setup.exe which will now be able to find the \sources\install.wim file on the Y: virtual DVD drive mounted by ImDisk

If required, we can also inject an XML file into the X:\Windows\System32 folder and specify this as the unattend file when we run setup.exe. This will cause Setup to be automated.

For MBR-bootong, it is necessary to swap the BIOS drives 0 (USB drive) and 1 around so that Windows will think the 'boot' drive is the internal hard disk and not the USB drive - otherwise Windows will refuse to install the boot code (and the Windows OS) to the first internal hard disk.

You can use VBox+VMUB to test (see Tutorial 4) but the grub2 drivemap command can cause WinPE to hang and not boot in a VM.

Example grub2 MBR menu:

menuentry "WIN10 Install" --unrestricted --class Windows {

set isoname=win10.iso

loopback loop /$isoname

linux16 /wimboot/wimboot

initrd16 \

newc:bcd:(loop)/boot/bcd \

newc:null.cfg:/wimboot/null.cfg \

newc:winpeshl.ini:/wimboot/winpeshl.ini \

newc:startup.bat.sdi:/wimboot/startup.bat \

newc:boot.sdi:(loop)/boot/boot.sdi \

newc:boot.wim:(loop)/sources/boot.wim

drivemap -s hd0 hd1

boot

)

Note: filenames defined after newc: must not be bigger than 31 characters or wimboot will fail.

Also grub is case sensitive so beware! - e.g. /Boot/boot.sdi instead of /boot/boot.sdi.

wimboot will try to locate a suitable bootmgr or bootxxx.efi boot file, so you don't usually need to specify one.

You can also add in bootmgr.exe or bootmgr or bootx64.efi/bootmgfw.efi files if the wim file does not contain a suitable file (copy the files to the \wimboot folder)

iPXEwimboot is used for MBR booting but a special grub2 (unsigned, non-secure) version of grub2 with wimboot.mod is required for UEFI-booting.

Example MBR grub4dos menu:

title Install Windows10x64UK_Oct_2018 using wimboot method

map /Windows10x64UK_Oct_2018.iso (0xff)

map --hook

root (0xff)

# the root path now points to the files inside the ISO file

# hd0,0 is the USB drive that we booted from

kernel (hd0,0)/wimboot/wimboot

initrd @null.cfg=/wimboot/null.cfg @startup.bat=(hd0,0)/wimboot/startup.bat @winpeshl.ini=(hd0,0)/wimboot/winpeshl.ini @bcd=/boot/bcd @boot.sdi=/boot/boot.sdi @boot.wim=/sources/boot.wim

map (hd0) (hd1)

map (hd1) (hd0)

map --hook

boot

IMPORTANT: order of the files in the initrd line seems to be important, the bcd and .wim file should be the last files loaded for the MBR version of wimboot.

On our USB drive we have a \wimboot folder:

wimboot

winpeshl.ini

startup.bat

null.cfg (contains the line installiso=xxxxxxxxx where xxxxxxxxx is the path and filename of the ISO using forward slashes)

\(the windows install iso)

Example winpeshl.ini

[LaunchApps]

startup.bat

Adding a 'Windows Install from ISO' menu to the E2B grub2 menu system

Set up your E2B drive with a second partition and the E2B grub2 menu files FIRST, then switch to the .imgPTN23 file so that the first partition contains the standard grub2 boot menu system files and the second partition contains your grub2 menu folders (e.g. \_ISO\MAINMENU, etc.) and then...

The following windows_install.grub2 menu text file can be added to the \_ISO\MAINMENU folder on the 2nd partition.

    1. Download the grub2_wimboot files - extract it onto the root of the 2nd partition so you have a new \wimboot folder

    2. Download the windows_install.grub2 file and copy it to \_ISO\MAINMENU\grub2 folder on the 2nd E2B partition. Rename it as custom_menu.grub2 if using grub2 Beta 10 or later.

    3. Create a new \_ISO\MAINMENU\WINDOWS folder (must be in capital letters) on the 2nd partition and place all your Windows Install ISOs in that folder.

This is for MBR booting

2nd partition (additions)

\wimboot folder

\_ISO\MAINMENU\grub2\custom_menu.grub2

\_ISO\MAINMENU\WINDOWS\ (your windows isos here)

Note: E2B grub2 v10W.imgPTN already includes wimboot and a new Windows Install W menu (you just copy your ISOs to the 2nd partition!) - see next section below...

Add grub2 UEFI + wimboot (using a1ive grub2)

I suggest you use the latest E2B grub2 v10W .imgPTN file - see bottom of this page for instructions.

The following instructions are for the v10A E2B grub2 menu system and is more difficult to set up...

A1ive has added a wimboot grub2 module into his special version of grub2 (unsigned).

1. Download the grub2 UEFI zip file

2. Extract the files to the \EFI\BOOT folder on the first FAT32 partition (after switching in the E2B grub2 .imgPTN file)

3. Use the windows_install.grub2 menu file (copy to \_ISO\MAINMENU\grub2 folder)

4. Place all your Windows Install ISO files in the \_ISO\MAINMENU\WINDOWS folder - must end in .ISO or .iso.

5. Add this line into one of the customX_menu.grub2 files at the very bottom to add in the windows menu

source $isofpath/grub2/windows_install.grub2

The E2B grub2 menu system will automatically add-in any customX_menu.grub2 files but the source line is required so that it adds in the windows_install.grub2 menu (or rename it as custom3_menu.grub2 instead if you wish),

The Windows ISOs will be automatically added into the main grub2 menu when you boot. If you have placed Windows Install ISOs in the \_ISO\MAINMENU\WINDOWS folder, they should be listed in the grub2 menu when you boot.

The ISO filename can contain spaces. It must end in .ISO or .iso (case sensitive - so not .ISo for instance).

Standard Microsoft dual-architecture Install ISOs are supported, x64 will be used if the CPU is a 64-bit processor.

For MBR-booting, the menu may run bootmgr and then hang on a Virtual Machine due to the drivemap command - so test on a REAL SYSTEM if you have boot problems on a VM.

\_ISO\MAINMENU\grub2\windows_install.grub2

#WINDOWS INSTALL MENU

#$isofpath e.g. (hd0,msdos2)/_ISO/LINUX - use only in if [ -e tests

#$root2 e.g. (hd0,msdos2) partition containing payload files

#$root e.g. hd0,msdos1 boot partition with grub2 on it

#$root2uuid e.g. 1234-2123-33 (uuid of $root2)

#Special variables: MBR EFI MBR32 MBR64 EFI32 EFI64 BIT32 BIT64 FAT (true if filesystem on ptn2 is FAT)

#Examples:

#if $BIT32 ; then echo 32-bit ; fi

#if ! $BIT64 ; then echo not 64-bit ; fi

#if [ $BIT64 = true and $FAT = true ] ; then echo 64-bit MBR on FAT partititon ; fi

#if [ $BIT64 = true and $EFI = true ] ; then echo 64-bit EFI (same as \$EFI64) ; fi

#CHECK_MNU_FOLDER sets these variables on return - do not use filename and filenamex inside menuentry

#$ip e.g. /_ISO/LINUX

#$ipf e.g. (hd0,msdos2)/_ISO/LINUX

#$isofile e.g. /_ISO/LINUX/xxxx.iso

#supports filenames with spaces

function ListWimBoot {

echo Adding WINDOWS ISO files from $ifp/WINDOWS

for file in $ifp/WINDOWS/*.iso $ifp/WINDOWS/*.ISO; do

if ! test -f "$file"; then continue; fi

regexp -s filename "$ip/WINDOWS/(.*)" "$file"

regexp -s filenamex "$ip/WINDOWS/(.*)(.[iI][Ss][oO])" "$file"

# echo $file


menuentry "${filenamex}" "${filename}" {

#do not use $filename inside menuentry - use $isoname instead!

set isoname="$2" ; CHECK_MNU_FOLDER

#ip, ipf and isofile are now set correctly after CHECK_MNU_FOLDER

loopback loop "${ipf}/WINDOWS/${isoname}"

set pp=

if test -f (loop)/x64/sources/boot.wim; then set pp=/x64; fi

if $MBR32; then

if test -f (loop)/x86/sources/boot.wim; then set pp=/x86; fi

fi

echo Using ${pp}/sources/boot.wim...

set root=$root2

set installiso="${ip}/WINDOWS/${isoname}"

save_env -f /wimboot/null.cfg installiso

# cat /wimboot/null.cfg

# read


linux16 /wimboot/wimboot

initrd16 \

# newc:bootmgr:(loop)${pp}/bootmgr \

newc:winpeshl.ini:/wimboot/winpeshl.ini \

newc:null.cfg:/wimboot/null.cfg \

newc:startup.bat:/wimboot/startup.bat \

newc:boot.wim:(loop)${pp}/sources/boot.wim \

newc:bcd:(loop)${pp}/boot/bcd \

newc:boot.sdi:(loop)${pp}/boot/boot.sdi

#swap hd0 (USB) with hd1 (internal hdd) so 'boot disk' is internal hdd

#this means may only work on real system

drivemap -s hd0 hd1

boot

}


done

}

function ListWimBootEFI {

echo Adding WINDOWS ISO files from $ifp/WINDOWS/

for file in $ifp/WINDOWS/*.iso $ifp/WINDOWS/*.ISO; do

if ! test -f "$file"; then continue; fi

regexp -s filename "$ip/WINDOWS/(.*)" "$file"

regexp -s filenamex "$ip/WINDOWS/(.*)(.[iI][Ss][oO])" "$file"

# echo $file


menuentry "${filenamex} EFI" "${filename}" {

set isoname="$2" ; CHECK_MNU_FOLDER

#ip ipf and isofile are now set correctly after CHECK_MNU_FOLDER

loopback loop "${ipf}/WINDOWS/${isoname}"

set pp=

if test -f (loop)/x64/sources/boot.wim; then set pp=/x64; fi

set bootmg=bootia32.efi

if $EFI32; then

if test -f (loop)/x86/sources/boot.wim; then set pp=/x86; fi

set bootmg=bootx64.efi

fi

echo Using ${pp}/sources/boot.wim...

set root=$root2

set installiso="${ip}/WINDOWS/${isoname}"

save_env -f /wimboot/null.cfg installiso

# cat /wimboot/null.cfg

# read

#NOTE: ORDER IS IMPORTANT! May get 0xC000000f error if order is wrong! boot.wim should be first.

#use wimboot --pause to see any error ( also --rawbcd --rawwim --index=1 --gui )

wimboot \

@:startup.bat:/wimboot/startup.bat \

@:winpeshl.ini:/wimboot/winpeshl.ini \

@:null.cfg:/wimboot/null.cfg \

@:boot.wim:(loop)${pp}/sources/boot.wim \

# @:bootmgfw.efi:(loop)${pp}/efi/boot/$bootmg \

@:bcd:(loop)${pp}/efi/microsoft/boot/bcd \

@:boot.sdi:(loop)${pp}/boot/boot.sdi

boot

}


done

}

if ! $EFI ; then ListWimBoot; fi

if $EFI ; then ListWimBootEFI; fi

If wimboot uses an incorrect bootmgr/bootgmfw.efi file you may get a 0xc000000f unknown error BSOD - it is often better to not specify this file and let wimboot find it.

Note that the full path of the ISO is placed in null.cfg which is later picked up by startup.bat.

Example startup.bat file:

@echo off

TITLE %~dpnx0 (WIMBOOT startup.bat)

wpeinit.exe

REM prevent wpeinit from running again

ren X:\windows\system32\wpeinit.exe wpeinit.exe.old

for %%I in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %%I:\wimboot\startup.bat set USBDRIVE=%%I:

IF "%USBDRIVE%"=="" (

echo ERROR - could not find \wimboot\startup.bat on any drive!

@echo on

for %%I in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %%I:\wimboot\startup.bat set USBDRIVE=%%I:

pause

goto :EOF

)

color 1f

cls

@echo FOUND USB DRIVE AT DRIVE %USBDRIVE%

SET BIT=32

if "%PROCESSOR_ARCHITECTURE%"=="AMD64" SET BIT=64

FOR /L %%A IN (0,1,5000) DO ECHO NOTHING > nul

:: get path of the ISO into MYISO e.g. /_ISO/WINDOWS/WIN10/Windows10ProBoth.iso

cd /d %USBDRIVE%\

set MYISO=INVALID_ISO_NAME.ISO

echo Looking for X:\Windows\System32\null.cfg contents...

for /f "tokens=1,2 delims==" %%a in ('find "installiso=" X:\Windows\System32\null.cfg') do set isopath=%%b

REM change linux forward slash to Windows backslash

set string1=%isopath:/=\%

if exist "%USBDRIVE%%string1%" set MYISO=%string1%

if not exist "%USBDRIVE%%MYISO%" if exist X:\Windows\System32\null.cfg type X:\Windows\System32\null.cfg

if not exist "%USBDRIVE%%MYISO%" echo ERROR: Can't find %USBDRIVE%%MYISO% && pause && goto :EOF

if exist "%USBDRIVE%%MYISO%" echo Loading %USBDRIVE%%MYISO%...

REM Load ISO using ImDisk

TITLE LOAD WINDOWS ISO USING IMDISK

call \wimboot\imdisk\IMDISK_install.cmd

call \wimboot\imdisk\IMDISK_instiso.cmd

REM Find mounted DVD drive

set DVDDRIVE=

FOR %%D IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO (

DIR %%D:\SOURCES\install.* > nul 2>&1 && (call set DVDDRIVE=%%D:) && echo FOUND %%D:\SOURCES\install.*

)

FOR %%D IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO (

DIR %%D:\SOURCES\x86\install.* > nul 2>&1 && (call set DVDDRIVE=%%D:) && echo FOUND %%D:\SOURCES\x86\install.*

)

FOR %%D IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO (

DIR %%D:\SOURCES\x64\install.* > nul 2>&1 && (call set DVDDRIVE=%%D:) && echo FOUND %%D:\SOURCES\x64\install.*

)

FOR %%D IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO (

DIR %%D:\x86\SOURCES\install.* > nul 2>&1 && (call set DVDDRIVE=%%D:) && echo FOUND %%D:\x86\SOURCES\install.*

)

FOR %%D IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO (

DIR %%D:\x64\SOURCES\install.* > nul 2>&1 && (call set DVDDRIVE=%%D:) && echo FOUND %%D:\x64\SOURCES\install.*

)

:ENDSEARCH

IF "%DVDDRIVE%"=="" echo WARNING: VIRTUAL DRIVE DRIVE NOT FOUND!

IF "%DVDDRIVE%"=="" echo WARNING: install.* not found on any mounted volume.

IF "%DVDDRIVE%"=="" pause

echo.

IF NOT "%DVDDRIVE%"=="" echo ISO FILE MOUNTED AS %DVDDRIVE%

REM startnet.cmd normally only contains wpeinit.exe, custom ISOs may contain other commands, so try to run them

if exist X:\WINDOWS\SYSTEM32\startnet.cmd call cmd /c X:\WINDOWS\SYSTEM32\startnet.cmd

if not exist X:\WINDOWS\SYSTEM32\startup.bat exit

IF "%DVDDRIVE%"=="" cmd

MODE CON COLS=30 LINES=2

echo DO NOT CLOSE THIS WINDOW

REM X:\Sources\setup.exe /Unattend:%E2BDRIVE%\AutoUnattend.xml

REM X:\Setup.exe will allow the repair option, X:\Sources\Setup.exe will directly run Setup

X:\setup.exe

The BCD

You must use a standard Microsoft WinPE BCD which is usually already present in a standard Microsoft Windows Install ISO.

Special WinPE ISOs tend to contain non-standard BCDs which will give a BSOD.

If in doubt, make a new BCD file using BootIce and copy it to the \wimboot folder so you can use it with wimboot.

The files will be placed by wimboot into their standard locations inside the RAMDisk that it makes so you must use standard names and paths in the BCD.

For UEFI - BCD must be set to boot from \sources\boot.wim and use \boot\boot.sdi and boot file=\Windows\system32\boot\winload.efi

For MBR - BCD must be set to boot from \sources\boot.wim and use \boot\boot.sdi and boot file=\Windows\system32\boot\winload.exe

If you get an error check that the winload file exists in the correct path inside the boot.wim by using 7Zip to open the ISO and \sources\boot.wim file.

Note: A solid black checkbox indicates 'not defined in BCD'.

wimboot command line

wimboot will parse the following extra commands on the same line (e.g. linux16 /wimboot pause):

rawbcd Use raw (unpatched) BCD files

rawwim Use raw (unpatched) WIM files

gui Allow graphical output from bootmgr/bootmgfw

pause Pause before booting OS

pause=quiet Pause without displaying any prompt

index=n WIM boot index

initrdfile Ignored to allow to be used with syslinux

after processing the command line, the files in the initrd ramdrive will be loaded.

For UEFI:

wimboot [--gui] [--rawbcd] [--rawwim] [--pause] [--index=n] @:boot.wim:/path/to/test.wim @:bootmgfw.efi:/path/to/test.efi @:bcd:/path/to/bcd @:boot.sdi:/path/to/boot.sdi * params: * --gui or -g Display graphical boot messages. * --rawbcd or -b Disable rewriting .exe to .efi in the BCD file. * --rawwim or -w Disable patching the wim file. * --pause or -p * --index=n or -i n Use WIM image index n.

File Injection into \Windows\System32

Files named 'BCD', or ending in '.wim' or '.sdi' are ignored and are not injected into the X:\Windows\System32 folder.

All other files added using wimboot will be added to the X:\windows\system32 folder with the new name that you specify.

Make your own grub2 boot files

The bootx64.efi and bootia32.efi files are stub files which load grubx64.efi and grubia32.efi.

To build you own grub2 files, download a build from here.

C:\TEMP\builds-master\

.gitignore

build_grub.bat <<< run this

grub-install.exe

grub-mkimage.exe

README.md

+---arch

| +---arm64

| +---ia32

| +---legacy

| | \---ntboot

| | \---NTBOOT.MOD

| \---x64

+---i386-efi

+---i386-pc

+---locale

\---x86_64-efi

Double-click on build_grub.bat to make new core.img, grubx64.efi and grubia32.efi boot files.

The builtin.lst files under the arch folder contain a list of modules which will be added into grub2.

The EFI files will be unsigned and so will not Secure Boot.

Example WinPE E2B .grub2 menus

Download custom2_menu.grub2 for WinPE files.

Create a .grub2 menu - e.g. \_ISO\MAINMENU\grub2\custom2_menu.grub2 in the 2nd E2B partition.

#WINDOWS PE EXAMPLES

# uses iPXE wimboot (2017-05-1) 30242 bytes http://ipxe.org/wimboot#download

# \wimboot folder on Partition 2 should contain wimboot, bootmgr, bootmgr.exe

# bootmgr.exe can be found in \Windows\Boot\PXE folder - copy it to the USB:\wimboot folder

#$isofpath e.g. (hd0,msdos2)/_ISO/LINUX - use only in if [ -e tests

#$root2 e.g. (hd0,msdos2) partition containing payload files

#$root e.g. hd0,msdos1 boot partition with grub2 on it

#$root2uuid e.g. 1234-2123-33 (uuid of $root2)

#Special variables: MBR EFI MBR32 MBR64 EFI32 EFI64 BIT32 BIT64 FAT (true if filesystem on ptn2 is FAT)

#Examples:

#if $BIT32 ; then echo 32-bit ; fi

#if ! $BIT64 ; then echo not 64-bit ; fi

#if [ $BIT64 = true and $FAT = true ] ; then echo 64-bit MBR on FAT partititon ; fi

#if [ $BIT64 = true and $EFI = true ] ; then echo 64-bit EFI (same as \$EFI64) ; fi

#CHECK_MNU_FOLDER sets these variables on return

#$ip e.g. /_ISO/LINUX

#$ifp e.g. (hd0,msdos2)/_ISO/LINUX

#$isofile e.g. /_ISO/LINUX/xxxx.iso

# ---------------------

function GetWimbootFiles {

#This function looks for files needed for iPXE WIMBOOT

#The filenames are case-sensitive, so we try to look for most likely ones!

set pp=

if test -f (loop)/x64/sources/boot.wim; then set pp=/x64; fi

if test -f (loop)/x64/Sources/boot.wim; then set pp=/x64; fi

if test -f (loop)/x64/Sources/Boot.wim; then set pp=/x64; fi

if test -f (loop)/x64/Sources/BOOT.wim; then set pp=/x64; fi

if test -f (loop)/x64/Sources/BOOT.WIM; then set pp=/x64; fi

if $BIT32; then

if test -f (loop)/x86/sources/boot.wim; then set pp=/x86; fi

if test -f (loop)/x86/Sources/boot.wim; then set pp=/x86; fi

if test -f (loop)/x86/Sources/Boot.wim; then set pp=/x86; fi

if test -f (loop)/x86/Sources/BOOT.wim; then set pp=/x86; fi

if test -f (loop)/x86/Sources/BOOT.WIM; then set pp=/x86; fi

fi

unset bme

if [ -e "/wimboot/bootmgr.exe" ]; then set bme=/wimboot/bootmgr.exe ; fi

if [ -e "(loop)/bootmgr.exe" ]; then set bme=(loop)/bootmgr.exe ; fi

if [ -e "(loop)/BOOTMGR.EXE" ]; then set bme=(loop)/BOOTMGR.EXE ; fi

if [ -e "(loop)/BOOTMGR.exe" ]; then set bme=(loop)/BOOTMGR.exe ; fi

if [ -e "(loop)/Bootmgr.exe" ]; then set bme=(loop)/Bootmgr.exe ; fi

unset bm1

if [ -e "/wimboot/bootmgr" ]; then set bm1=/wimboot/bootmgr ; fi

if [ -e "(loop)/bootmgr" ]; then set bm1=(loop)/bootmgr ; fi

if [ -e "(loop)/Bootmgr" ]; then set bm1=(loop)/Bootmgr ; fi

if [ -e "(loop)/BOOTMGR" ]; then set bm1=(loop)/BOOTMGR ; fi

unset bcd

if [ -e "(loop)${pp}/BOOT/BCD" ]; then set bcd=(loop)${pp}/BOOT/BCD ; fi

if [ -e "(loop)${pp}/BOOT/bcd" ]; then set bcd=(loop)${pp}/BOOT/bcd ; fi

if [ -e "(loop)${pp}/BOOT/Bcd" ]; then set bcd=(loop)${pp}/BOOT/bcd ; fi

if [ -e "(loop)${pp}/Boot/BCD" ]; then set bcd=(loop)${pp}/Boot/BCD ; fi

if [ -e "(loop)${pp}/Boot/bcd" ]; then set bcd=(loop)${pp}/Boot/bcd ; fi

if [ -e "(loop)${pp}/Boot/Bcd" ]; then set bcd=(loop)${pp}/Boot/bcd ; fi

if [ -e "(loop)${pp}/boot/BCD" ]; then set bcd=(loop)${pp}/boot/BCD ; fi

if [ -e "(loop)${pp}/boot/bcd" ]; then set bcd=(loop)${pp}/boot/bcd ; fi

if [ -e "(loop)${pp}/boot/Bcd" ]; then set bcd=(loop)${pp}/boot/bcd ; fi

unset sdi

if [ -e "(loop)${pp}/BOOT/BOOT.SDI" ]; then set sdi=(loop)${pp}/BOOT/BOOT.SDI ; fi

if [ -e "(loop)${pp}/BOOT/boot.sdi" ]; then set sdi=(loop)${pp}/BOOT/BOOT.SDI ; fi

if [ -e "(loop)${pp}/BOOT/Boot.sdi" ]; then set sdi=(loop)${pp}/BOOT/BOOT.SDI ; fi

if [ -e "(loop)${pp}/Boot/BOOT.SDI" ]; then set sdi=(loop)${pp}/Boot/BOOT.SDI ; fi

if [ -e "(loop)${pp}/Boot/boot.sdi" ]; then set sdi=(loop)${pp}/Boot/boot.sdi ; fi

if [ -e "(loop)${pp}/Boot/Boot.sdi" ]; then set sdi=(loop)${pp}/Boot/BOOT.SDI ; fi

if [ -e "(loop)${pp}/boot/BOOT.SDI" ]; then set sdi=(loop)${pp}/boot/BOOT.SDI ; fi

if [ -e "(loop)${pp}/boot/boot.sdi" ]; then set sdi=(loop)${pp}/boot/boot.sdi ; fi

if [ -e "(loop)${pp}/boot/Boot.sdi" ]; then set sdi=(loop)${pp}/boot/BOOT.sdi ; fi

unset wim

if [ -e "(loop)${pp}/sources/boot.wim" ]; then set wim=(loop)${pp}/sources/boot.wim ; fi

if [ -e "(loop)${pp}/Sources/boot.wim" ]; then set wim=(loop)${pp}/Sources/boot.wim ; fi

if [ -e "(loop)${pp}/Sources/Boot.wim" ]; then set wim=(loop)${pp}/Sources/Boot.wim ; fi

if [ -e "(loop)${pp}/SOURCES/boot.wim" ]; then set wim=(loop)${pp}/SOURCES/boot.wim ; fi

if [ -e "(loop)${pp}/SOURCES/Boot.wim" ]; then set wim=(loop)${pp}/SOURCES/Boot.wim ; fi

if [ -e "(loop)${pp}/SOURCES/BOOT.wim" ]; then set wim=(loop)${pp}/SOURCES/BOOT.wim ; fi

if [ -e "(loop)${pp}/SOURCES/BOOT.WIM" ]; then set wim=(loop)${pp}/SOURCES/BOOT.WIM ; fi

unset bmefi64

set t="(loop)${pp}/bootmgr.efi" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/EFI/BOOT/BOOTX64.EFI" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/EFI/BOOT/Bootx64.efi" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/EFI/BOOT/bootx64.efi" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/EFI/Boot/BOOTX64.EFI" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/EFI/Boot/Bootx64.efi" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/EFI/Boot/bootx64.efi" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/Efi/BOOT/BOOTX64.EFI" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/Efi/BOOT/Bootx64.efi" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/Efi/BOOT/bootx64.efi" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/efi/Boot/BOOTX64.EFI" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/efi/Boot/Bootx64.efi" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

set t="(loop)${pp}/efi/Boot/bootx64.efi" ; if [ -e "$t" ]; then set bmefi64="$t" ; fi

unset bmefi32

set t="(loop)${pp}/bootmgr.efi" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/EFI/BOOT/BOOTX64.EFI" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/EFI/BOOT/Bootx64.efi" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/EFI/BOOT/bootx64.efi" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/EFI/Boot/BOOTX64.EFI" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/EFI/Boot/Bootx64.efi" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/EFI/Boot/bootx64.efi" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/Efi/BOOT/BOOTX64.EFI" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/Efi/BOOT/Bootx64.efi" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/Efi/BOOT/bootx64.efi" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/efi/Boot/BOOTX64.EFI" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/efi/Boot/Bootx64.efi" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

set t="(loop)${pp}/efi/Boot/bootx64.efi" ; if [ -e "$t" ]; then set bmefi32="$t" ; fi

#either bootmgr.exe or bootmgr is required. It can be inside the boot.wim file


if ! [ -e /wimboot/wimboot ]; then echo ERROR: /wimboot/wimboot does not exist! Please add /wimboot folder to Partition 2 ; read ; fi

echo

if [ "$bme" = "" ]; then echo WARNING: bootmgr.exe not found ; fi

if [ "$bm1" = "" ]; then echo WARNING: bootmgr not found ; fi

if [ "$bme" = "" -a "$bm1" = "" ]; then set werr=1 ; fi

if [ "$bcd" = "" ]; then echo ERROR: BCD not found in ISO file ; set werr=1 ; fi

if [ "$sdi" = "" ]; then echo ERROR: boot.sdi not found in ISO file ; set werr=1 ; fi

if [ "$wim" = "" ]; then echo ERROR: boot.wim not found in ISO file ; set werr=1 ; fi

echo Using:

echo bm1=$bm1

echo bme=$bme

echo bcd=$bcd

echo sdi=$sdi

echo wim=$wim

echo bmefi64=$bmefi64

echo bmefi32=$bmefi32

echo --------

if [ "$werr" = "1" ]; then echo Possible error: Press a key to continue anyway... ; read ; fi

}

# ---------- Win10PESE_x64.ISO ------

if $MBR64; then

if [ -e "$isofpath/Win10PESE_x64.ISO" ]; then

menuentry "Win10PESE_x64.ISO (BIOS WIMBOOT)" --unrestricted --class windows {

set isoname=Win10PESE_x64.ISO ; CHECK_MNU_FOLDER

set root=$root2

loopback loop $isofile

GetWimbootFiles

linux16 /wimboot/wimboot pause

initrd16 \

# newc:bootmgr:$bm1 \

newc:boot.sdi:$sdi \

newc:boot.wim:$wim \

newc:bcd:$bcd

boot

}

fi

fi

#This menu will be shown for 32-bit and 64-bit CPUs

if $EFI; then

if [ -e "$isofpath/Win10PESE_x64.ISO" ]; then

menuentry "Win10PESE_x64.ISO (UEFI WIMBOOT)" --unrestricted --class windows {

set isoname=Win10PESE_x64.ISO ; CHECK_MNU_FOLDER

set root=$root2

loopback loop "$isofile"

# GetWimbootFiles

set pp=

if test -f (loop)/x64/sources/boot.wim; then set pp=/x64; fi

if $EFI32; then

if test -f (loop)/x86/sources/boot.wim; then set pp=/x86; fi

fi

echo Using ${pp}/sources/boot.wim...

wimboot --pause \

@:boot.sdi:(loop)${pp}/Boot/boot.sdi \

# @:bootmgfw.efi:(loop)${pp}/efi/boot/bootx64.efi \

@:boot.wim:(loop)${pp}/sources/boot.wim \

@:bcd:(loop)${pp}/efi/microsoft/boot/bcd

boot

}

fi

fi

# ------------- Win10XPE_X64.iso ----------------------

#WORKS (wimboot doesn't work)

if $MBR64; then

if [ -e "$isofpath/Win10XPE_x64.ISO" ]; then

menuentry "Win10XPE_x64 (BIOS MEMDISK)" --unrestricted --class windows {

set isoname=Win10XPE_x64.ISO ; CHECK_MNU_FOLDER

linux16 ($root)/boot/grub/memdisk iso raw

set root=$root2

initrd16 $isofile

# drivemap -s (hd0) (hd1)

boot

}

fi

fi

# ----------- ampe64.iso ------------------

if $MBR64; then

if [ -e "$isofpath/ampe64.iso" ]; then

menuentry "ampe64.iso WORKS (BIOS WIMBOOT)" --unrestricted --class windows {

set isoname=ampe64.iso ; CHECK_MNU_FOLDER

set root=$root2

loopback loop $isofile

GetWimbootFiles

linux16 /wimboot/wimboot pause

initrd16 \

# newc:bootmgr:$bm1 \

newc:boot.sdi:$sdi \

newc:boot.wim:$wim \

newc:bcd:$bcd

boot

}

fi

fi

#This menu will be shown for 32-bit and 64-bit CPUs

if $EFI; then

if [ -e "$isofpath/ampe64.iso" ]; then

menuentry "ampe64.iso (UEFI WIMBOOT)" --unrestricted --class windows {

set isoname=ampe64.iso ; CHECK_MNU_FOLDER

set root=$root2

loopback loop "$isofile"

GetWimbootFiles

if [ "$bmefi64" = "" ]; then echo ERROR: bootmgr EFI file not found ; fi

if [ "$sdi" = "" ]; then echo ERROR: boot.sdi file not found ; fi

if [ "$wim" = "" ]; then echo ERROR: boot.wim file not found ; fi

if [ "$bcd" = "" ]; then echo ERROR: BCD file not found ; fi

echo Using $wim...

wimboot --pause \

# @:bootmgfw.efi:$bmefi64 \

@:boot.sdi:$sdi \

@:boot.wim:$wim \

@:bcd:$bcd


echo boot...

read

boot

}

fi

fi

# Strelec WinPE TEST

# This menu will be shown for 32-bit and 64-bit CPUs

# Make strelec_BCD using BootIce - BCD must be set to boot from \sources\boot.wim and use \boot\boot.sdi and boot file=\Windows\system32\boot\winload.efi

# Need to obtain missing bootx64.efi from a standard Win10 ISO and add to \wimboot folder

# Once at Desktop, right-click on Strelec ISO in Explorer and MOUNT as Y: - then run MistAll from start menu

if $EFI64; then

if [ -e "$isofpath/WinPE10_8_Sergei_Strelec_x86_x64_2019.02.04_English.iso" ]; then

menuentry "TEST WinPE10_8_Sergei_Strelec_x86_x64_2019.02.04_English.iso (UEFI WINPE WIMBOOT)" --unrestricted --class windows {

set isoname=WinPE10_8_Sergei_Strelec_x86_x64_2019.02.04_English.iso ; CHECK_MNU_FOLDER

set root=$root2

loopback loop "$isofile"

wimboot --pause \

@:boot.sdi:(loop)/SSTR/boot.sdi \

@:bootmgfw.efi:/wimboot/bootx64.efi \

@:boot.wim:(loop)/SSTR/strelec10x64Eng.wim \

@:bcd:/wimboot/strelec64_BCD

boot

}

fi

fi

-------------------------------------------------

grub2 UEFI + wimboot (iPXE)

You can use the iPXE environment instead of a grub2 environment

\boot.ipxe - config file run by iPXE

\ipxe64.efi - contains iPXE boot code (x64)

\ipxe32.efi - contains iPXE boot code (32-bit)

\wimboot - the wimboot code

\win\boot64.wim - \win folder contains your bootable wim file (any name)

\win\BCD2 - and name for BCD

\win\boot.sdi - generic boot.sdi

1. Go to the ROMMatic site and create a 64-bit and 32-bit .EFI file using - Advanced - EFI PXE bootstrap xx-bit (.efi)

and paste in the following script in the Embedded script box at the bottom:

#!ipxe

chain file:/boot.ipxe

then click on Proceed and wait (if you get a timeout - try again)

2. Now you should have a ipxe64.efi file and a ipxe32.efi file which you can load from grub2:

menuentry "iPXE wimboot" {

chainloader /ipxe64.efi

boot

}

3. Create the iPXE config file \boot.ipxe

#!ipxe

#use --name for UEFI when file has different name from default

#add second virtual name for MBR booting

#ensure BCD has standard \sources\boot.wim and \sources\boot.sdi paths

ifopen

kernel file:/wimboot

initrd --name bcd file:/win/bcd2 bcd

initrd --name boot.sdi file:/win/boot.sdi boot.sdi

initrd --name boot.wim file:/win/boot64.wim boot.wim

echo

echo Platform=${platform} BuildArch=${buildarch}

echo

imgstat

prompt --timeout 5000 Press a key... ||

boot

The same boot.sdi file can be used by all Windows 7/8/10 etc. AFAIK.

4. Use BootIce to ensure that the BCD2 file has standard file paths for the boot.wim and boot.sdi

If these paths are not 'standard', then you will get a BSOD 0xc000000f error!

See iPXE wimboot description for more details.

The big problem with this method is that the boot.ipxe configuration file cannot be passed the path of the boot.wim file by grub. Once grub chainloads the .efi boot file, all connections with grub are lost.

This means that you can only boot to one boot.wim OR you must prompt the user to enter path of the boot.wim file by adding scripting into the boot.ipxe file,

e.g.

echo Please enter the full path of the boot.wim file...

read wimboot

and then use

initrd --name boot.wim file:$wimboot boot.wim

in the boot.iPXE menuentry...

#!ipxe

#use --name for UEFI when file has different name from default

#add second virtual name for MBR booting

#ensure BCD has standard \sources\boot.wim and \sources\boot.sdi paths

ifopen

:getwim

imgfree

echo

echo

echo Please enter the full path of the boot.wim file...

echo Press ENTER for /win/boot64.wim

clear wimboot

echo

read wimboot

isset ${wimboot} || set wimboot /win/boot64.wim

echo wimboot=${wimboot}

#check file exists

imgfetch file:${wimboot} || goto getwim

read ask

kernel file:/wimboot

initrd --name bcd file:/win/bcd2 bcd

initrd --name boot.sdi file:/win/boot.sdi boot.sdi

initrd --name boot.wim file:${wimboot} boot.wim

echo

echo Platform=${platform} BuildArch=${buildarch}

echo

imgstat

prompt --timeout 5000 Press a key... ||

boot