@echo off
setlocal enabledelayedexpansion
setlocal enableextensions
cd /d %~dp0
set HideDetails=Y
set Partition1Size=1000
set Part2SizeLimit=N
set Part2FS=NTFS
set Partition1Name=PAR-1-FAT32
set Partition2Name=PAR-2-%Part2FS%
set PartType=MBR
set AutoDismount=Y
:start
(Fsutil Dirty Query %SystemDrive%>Nul)||(PowerShell start """%~f0""" -verb RunAs & Exit /B)
call ::TOUPPERCASE HideDetails
call ::TOUPPERCASE Partition1Size
call ::TOUPPERCASE Part2SizeLimit
call ::TOUPPERCASE Part2FS
call ::TOUPPERCASE Partition1Name
call ::TOUPPERCASE PartType
call ::TOUPPERCASE AutoDismount
if %HideDetails%==Y (
set flag=/nfl /ndl
) ELSE (
set flag=
)
mode con: cols=120 lines=25
cls
echo Introduction
echo ============
echo.
echo This batch file will create a bootable flash drive from a mounted Windows ISO image or an image extracted to disk.
echo If you are using an ISO image, mount it before you continue by double-clicking the ISO image and note the drive
echo letter to which it is mounted.
echo.
echo You will be asked if you want to wipe the destination disk or perform a refresh operation. If this is the first
echo time preparing the disk, use the WIPE option. Be aware that this will destroy ALL data currently on the disk^^!
echo.
echo If you choose the REFRESH option, you will be asked for the drive letter of the two partitions previously
echo created on the disk. We will then replace the files on these partitions with those from the source that you
echo specify. This is especially helpful if you create additional partitions on the disk because it will update
echo the first two partitions while leaving any additional partitions intact.
echo.
pause
cls
echo Do you want to perform a WIPE operation or a REFRESH operation?
echo.
choice /C WR /N /M "Press W or R to respond:"
if errorlevel 2 set WipeRefresh=REFRESH & goto GetSourcePath
if errorlevel 1 set WipeRefresh=WIPE & goto GetSourcePath
:GetSourcePath
cls
echo Please enter the path to the SOURCE where your Windows files are located. This location can be a folder on a
echo HDD, SSD, etc. or it can be a mounted Windows ISO image. The path can end with or without a backslash (\).
echo The following are all examples of valid paths:
echo.
echo D:, D:\, D:\ISO_Files, D:\ISO_Files\ are all valid paths.
echo.
echo Enter the path to the SOURCE where your Windows files are located below.
echo.
:GetSourcePath
set /p SourcePath="Enter source path: "
IF NOT "%SourcePath:~-1%"=="\" (
set SourcePath=%SourcePath%\
)
if NOT EXIST %SourcePath%boot\bootfix.bin (
cls
echo The location that you specified does not contain a valid Windows image. Please try another location.
echo If you are specifying a location on disk, please be sure to specify the location to the root of the
echo Windows image. If you are using an ISO image, you should double-click the ISO image to mount it and
echo note the drive letter to which it was mounted.
echo.
goto GetSourcePath
)
if exist %SourcePath%\x64 (
set Architecture=DUAL
) ELSE (
set Architecture=SINGLE
)
If %WipeRefresh%==WIPE goto GetDiskNum
:GetPar1Letter
cls
echo Please enter the drive letter of the FIRST partition (the FAT32 partition) on the disk that we will refresh. Please
echo enter a drive letter only with no colon (:).
echo.
set /P Partition1="Drive letter of FIRST partition: "
if exist %Partition1%:\boot\bootfix.bin goto GetPar2Letter
cls
echo ERROR! Either the drive letter you specified does not exist or it does not seem to contain a previously
echo created partition with suitable Windows installation files.
echo.
echo Please verify that you have specified the correct drive letter.
echo.
pause
goto GetPar1Letter
:GetPar2Letter
cls
echo Please enter the drive letter of the SECOND partition (the exFAT or NTFS partition) on the disk that we will
echo refresh. Please enter a drive letter only with no colon (:).
echo.
set /P Partition2="Drive letter of SECOND partition: "
if exist %Partition2%:\Sources goto Par2Valid
if exist %Partition2%:\x64 goto Par2Valid
cls
echo ERROR! Either the drive letter you specified does not exist or it does not seem to contain a previously
echo created partition with suitable Windows installation files.
echo.
echo Please verify that you have specified the correct drive letter.
echo.
pause
goto GetPar2Letter
:Par2Valid
goto Summary
:GetDiskNum
cls
(echo list disk
echo exit
) | diskpart
echo.
echo Above is a list of disks connected to your system. Scroll up if the list is too long.
echo CAUTION: *MAKE SURE* that you specify the correct disk because it will be erased. Press CTRL + C to abort.
echo.
set /p DiskID="Enter the disk number for the DESTINATION disk (Enter only the number and press ENTER): "
if [%DiskID%] EQU [] Goto GetDiskNum
:Summary
cls
echo Summary of options you have selected:
echo.
call ::TOUPPERCASE SourcePath
echo Path for the source files: %SourcePath%
if %HideDetails%==Y (
echo File copy status details WILL NOT be displayed
) ELSE (
echo File copy status details WILL be displayed
)
if %AutoDismount%==Y (
echo The ISO image will be automatically dismounted when we are done with it
)
if %WipeRefresh%==REFRESH goto RefreshSummary
echo Drive number to make bootable: %DiskID%
echo Partition type: %PartType%
echo Partition 1 size: %Partition1Size% MB
echo Partition 2 filesystem type: %Part2FS%
if NOT %Part2SizeLimit%==N (
echo Partition 2 size: %Part2SizeLimit% MB
) ELSE (
echo Partition 2 size: Use all remaining space
)
echo Partition 1 volume label: %Partition1Name%
echo Partition 2 volume label: %Partition2Name%
goto GetConfirmation
:RefreshSummary
call ::TOUPPERCASE Partition1
call ::TOUPPERCASE Partition2
echo Drive letter of FIRST partition to refresh: %Partition1%:
echo Drive letter of SECOND partition to refresh: %Partition2%:
:GetConfirmation
echo.
choice /C YN /N /M "Is this correct? (Press Y or N to respond):"
if errorlevel 2 (
cls
echo.
echo Symptom Corrective Action
echo ======= =================
echo Source path is wrong: Run the program again and respond with the correct path
echo Wrong drive number for a WIPE: Run the program again and respond with the correct drive number
echo Wrong drive letters for a REFRESH: Run the program again and respond with the correct drive letters
echo File copy status display incorrect: Change the setting of "HideDetails" at start of program
echo Wrong partition sizes: Change the setting of "Partition1Size" or "Part2SizeLimit" at start of program
echo Wrong volume labels for a WIPE: Change the setting of "Partition1Name" or "Partition2Name" at start of program
echo Wrong partition type: Change the setting of "PartType" at start of program
echo.
pause
exit
)
cls
if %WipeRefresh%==WIPE echo We are performing the initial partitioning the destination drive to free up any used drive letters.
if %WipeRefresh%==REFRESH echo We are refreshing drives %Partition1%: and %Partition2%:. Other partitions will be left alone.
echo Please be patient^^! This can take a while if your drive is slow.
echo.
if %WipeRefresh%==REFRESH goto CopyOperations
(echo select disk %DiskID%
echo clean
echo convert %PartType%
echo rescan
echo exit
) | diskpart > nul
:GetPar1DriveLetter
cls
echo Please enter the drive letter to assign to the FIRST partition (the FAT32 partition). Please enter
echo a drive letter only with no colon (:).
echo.
set /p Partition1="Enter the drive letter to assign to Partition #1: "
if exist %Partition1%: (
echo.
echo That drive letter is already in use. Please choose another.
echo.
pause
goto GetPar1DriveLetter
)
:GetPar2DriveLetter
cls
echo Please enter the drive letter to assign to the SECOND partition (the NTFS partition). Please enter
echo a drive letter only with no colon (:).
echo.
set /p Partition2="Enter the drive letter to assign to Partition #2: "
if exist %Partition2%: (
echo.
echo That drive letter is already in use. Please choose another.
echo.
pause
goto GetPar2DriveLetter
)
call ::TOUPPERCASE Partition1
call ::TOUPPERCASE Partition2
cls
echo The first partition will be assigned drive letter %Partition1%: and will be formatted with FAT32.
(echo select disk %DiskID%
echo create partition primary size=%Partition1Size%
echo format fs=fat32 quick
echo assign letter=%Partition1%
echo active
echo rescan
echo exit
) | diskpart > nul
echo The second partition will be assigned drive letter %Partition2%: and will be formatted with %Part2FS%.
echo.
if %Part2SizeLimit%==N goto NoSizeLimit
(echo select disk %DiskID%
echo create partition primary size=%Part2SizeLimit%
echo format fs=%Part2FS% quick
echo assign letter=%Partition2%
echo rescan
echo exit
) | diskpart > nul
goto PartitionsCreated
:NoSizeLimit
(echo select disk %DiskID%
echo create partition primary
echo format fs=%Part2FS% quick
echo assign letter=%Partition2%
echo rescan
echo exit
) | diskpart > NUL
:PartitionsCreated
label %Partition1%:%Partition1Name%
label %Partition2%:%Partition2Name%
:CopyOperations
if %HideDetails%==Y (
echo Please be aware that the copying of files may take quite a while if your media is slow. Since you
echo have the variable called HideDetails set to Y, you will see no status below while files are being
echo copied. Please be patient and allow the process to finish.
echo.
)
if %Architecture%==DUAL goto DualArchitecture
robocopy "%SourcePath% " %Partition1%:\ /mir /xd sources "system volume information" $recycle.bin /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler1
robocopy "%SourcePath%sources " %Partition1%:\sources boot.wim /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler1
robocopy "%SourcePath%sources " %Partition2%:\sources /mir /njh /njs /xf boot.wim %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%boot " %Partition2%:\boot /mir /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%efi " %Partition2%:\efi /mir /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%support " %Partition2%:\support /mir /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%Partition1%:\ " "%Partition2%:\ " /mov autounattend*.xml /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
pause
if NOT exist %Partition2%:\sources\ei.cfg (
echo [CHANNEL] > %Partition2%:\sources\ei.cfg
echo Retail >> %Partition2%:\sources\ei.cfg
)
goto DoneCopying
:DualArchitecture
robocopy "%SourcePath% " %Partition1%:\ /mir /xd sources x64 x86 "system volume information" $recycle.bin /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler1
robocopy "%SourcePath%x64\sources " %Partition1%:\x64\sources boot.wim /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler1
robocopy "%SourcePath%x86\sources " %Partition1%:\x86\sources boot.wim /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler1
robocopy "%SourcePath%x64\sources " %Partition2%:\x64\sources /mir /njh /njs /xf boot.wim /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%x86\sources " %Partition2%:\x86\sources /mir /njh /njs /xf boot.wim /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%x64\boot " %Partition2%:\x64\boot /mir /njh /njs /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%x86\boot " %Partition2%:\x86\boot /mir /njh /njs /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%x64\efi " %Partition2%:\x64\efi /mir /njh /njs /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%x86\efi " %Partition2%:\x86\efi /mir /njh /njs /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%x64\support " %Partition2%:\x64\support /mir /njh /njs /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%SourcePath%x86\support " %Partition2%:\x86\support /mir /njh /njs /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
robocopy "%Partition1%:\ " "%Partition2%:\ " /mov autounattend*.xml /njh /njs %flag%
if %ERRORLEVEL% gtr 3 goto ErrorHandler2
if NOT exist %Partition2%:\x64\sources\ei.cfg (
echo [CHANNEL] > %Partition2%:\x64\sources\ei.cfg
echo Retail >> %Partition2%:\x64\sources\ei.cfg
)
if NOT exist %Partition2%:\x86\sources\ei.cfg (
echo [CHANNEL] > %Partition2%:\x86\sources\ei.cfg
echo Retail >> %Partition2%:\x86\sources\ei.cfg
)
:DoneCopying
IF %AutoDismount%==N goto DismountDone
IF "!SourcePath:~-1!"=="\" SET SourcePath=!SourcePath:~,-1!
powershell.exe -command "Dismount-DiskImage -DevicePath \\.\%SourcePath%" > NUL
:DismountDone
cls
echo ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
echo :: Checking to see if this system has BlackLotus UEFI Bootkit Secure Boot mitigations ::
echo :: installed. If it does, we will use this to make your boot disk compatible with ::
echo :: systems that have this update applied. Please note that we can only make this disk ::
echo :: compatible from systems that have this mitigation applied. ::
echo ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
echo.
for /f %%a in ('powershell "[System.Text.Encoding]::ASCII.GetString((Get-SecureBootUEFI db).bytes) -match 'Windows UEFI CA 2023'"') do set "PowerShellOutput=%%a"
if "%PowerShellOutput%"=="True" (
goto CheckCondition2
) else (
goto NotInstalled
)
:CheckCondition2
for /f %%a in ('powershell "[System.Text.Encoding]::ASCII.GetString((Get-SecureBootUEFI dbx).bytes) -match 'Microsoft Windows Production PCA 2011'"') do set "PowerShellOutput=%%a"
if "%PowerShellOutput%"=="True" (
goto Condition2True
) else (
goto NotInstalled
)
:Condition2True
attrib %Partition1%:\*.* -r /s /d > NUL 2>&1
COPY /Y %Partition1%:\EFI\MICROSOFT\BOOT\BCD %Partition1%:\EFI\MICROSOFT\BOOT\BCD.BAK > NUL
bcdboot c:\windows /f UEFI /s %Partition1%: /bootex > NUL 2>&1
COPY /Y %Partition1%:\EFI\MICROSOFT\BOOT\BCD.BAK %Partition1%:\EFI\MICROSOFT\BOOT\BCD > NUL
echo This system has the mitigations installed so we were able to patch your boot disk.
echo.
pause
goto DoneWithMitigation
:NotInstalled
echo This system does NOT have the mitigations installed so we are NOT able to patch your boot disk.
echo It is possible that disk may not boot on systems with those mitigations applied.
echo.
pause
goto DoneWithMitigation
:DoneWithMitigation
cls
echo All operations have been completed.
echo.
if exist %Partition2%:\autounattend.xml (
echo ^^!CAUTION^^! An unattended setup file ^(autounattend.xml^) is present on the 2nd partition.
echo As a result, if you boot from this disk, an unattended installation will begin. This has
echo the potential to wipe out the contents of disks attached to your system without warning.
echo.
echo It might be a wise idea to carefully label the bootable media to reflect this situation.
echo As an alternative, consider temporarily renaming the autounattend.xml to something else.
echo.
)
pause
:END
exit
:TOUPPERCASE
if not defined %~1 exit /b
for %%a in ("a=A" "b=B" "c=C" "d=D" "e=E" "f=F" "g=G" "h=H" "i=I" "j=J" "k=K" "l=L" "m=M" "n=N" "o=O" "p=P" "q=Q" "r=R" "s=S" "t=T" "u=U" "v=V" "w=W" "x=X" "y=Y" "z=Z" "ä=Ä" "ö=Ö" "ü=Ü") do (
call set %~1=%%%~1:%%~a%%
)
goto :eof
:ErrorHandler1
cls
echo There was an error copying files to partition #1. Please verify that partition #1 has sufficient space available.
echo Please correct the situation and run the script again. If you are changing the partition sizes, then you will
echo need to use the WIPE operation to create new partitions with the newly specified sizes.
echo.
pause
goto END
:ErrorHandler2
cls
echo There was an error copying files to partition #2. Please verify that partition #2 has sufficient space available.
echo Please correct the situation and run the script again. If you are changing the partition sizes, then you will
echo need to use the WIPE operation to create new partitions with the newly specified sizes.
echo.
pause
goto END