Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save viktoschi/4e1488eaf3fd811d98586dfe6e35d0aa to your computer and use it in GitHub Desktop.
Save viktoschi/4e1488eaf3fd811d98586dfe6e35d0aa to your computer and use it in GitHub Desktop.
# Declare some variables
$WinPE_Folder = "C:\WinPE10"
$WinPE_BuildFolder = $WinPE_Folder + "\WinPE10"
$WinPE_MountFolder = $WinPE_Folder + "\Mount"
$WinPE_Combined = $WinPE_Folder + "\WinPE10_Combined"
$WinPE_Media = $WinPE_Folder + "\Media"
$WinPE_Drivers = $WinPE_Folder + "\Drivers"
$WinPE_AppsFiles = $WinPE_Folder + "\Apps"
New-Item $WinPE_Drivers -Type Directory -force
New-Item $WinPE_AppsFiles -Type Directory -force
$ADK_Path = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit"
$WinPE_ADK_Path = $ADK_Path + "\Windows Preinstallation Environment"
$oscdimg_Path = $ADK_Path + "\Deployment Tools\amd64\Oscdimg\oscdimg.exe"
$bcdedit_Path = $ADK_Path + "\Deployment Tools\amd64\BCDBoot\bcdedit.exe"
$efiboot_Path = $ADK_Path + "\Deployment Tools\amd64\Oscdimg\efisys.bin"
$EFIbcd = $WinPE_Media + "\EFI\Microsoft"
$amd64 = "$WinPE_BuildFolder" + "_amd64"
$x86 = "$WinPE_BuildFolder" + "_x86"
$Language = "de-de"
$TimeStamp = Get-Date -Format dd_MM_yyyy;
$ISOLabel = "winpe_dualboot_$TimeStamp"
function Get-ScriptDirectory {
$Invocation = (Get-Variable MyInvocation -Scope 1).Value;
if($Invocation.PSScriptRoot)
{
$Invocation.PSScriptRoot;
}
Elseif($Invocation.MyCommand.Path)
{
Split-Path $Invocation.MyCommand.Path
}
else
{
$Invocation.InvocationName.Substring(0,$Invocation.InvocationName.LastIndexOf("\"));
}
}
$scriptroot = Get-ScriptDirectory
# Copy Drivers & Apps
robocopy "$scriptroot\addon\Drivers\" "$WinPE_Drivers" /e /NDL /NJH /NJS | %{$data = $_.Split([char]9);
if("$($data[4])" -ne "") { $file = "$($data[4])"} ;
Write-Progress "Percentage $($data[0])" -Activity "Copy files..." -CurrentOperation "$($file)" -ErrorAction SilentlyContinue; }
Write-Progress -Activity "Copy files..." -Completed
robocopy "$scriptroot\addon\Apps\" "$WinPE_AppsFiles" /e /NDL /NJH /NJS | %{$data = $_.Split([char]9);
if("$($data[4])" -ne "") { $file = "$($data[4])"} ;
Write-Progress "Percentage $($data[0])" -Activity "Copy files..." -CurrentOperation "$($file)" -ErrorAction SilentlyContinue; }
Write-Progress -Activity "Copy files..." -Completed
Function Make-WinPEBootWim($WinPE_Architecture){
# Paths to WinPE folders and tools
$WinPE_OCs_Path = $WinPE_ADK_Path + "\$WinPE_Architecture\WinPE_OCs"
$DISM_Path = $ADK_Path + "\Deployment Tools" + "\$WinPE_Architecture\DISM"
$WinPE_BuildFolder = $WinPE_BuildFolder + "_" + $WinPE_Architecture
Function Delete-Folder($folderPath){
try {
if (Test-Path -path $folderPath) {Remove-Item -Path $folderPath -Recurse -ErrorAction Stop}
}
catch{
Write-Warning "Error deleting folder!"
Write-Warning "Error: $($_.Exception.Message)"
Break
}
}
Function Make-Directory($folderPath){
if (!(Test-Path -path $folderPath)) {New-Item $folderPath -Type Directory}
}
Function WinPE-Mount($buildFolder, $mountFolder){
& $DISM_Path\Imagex.exe /mountrw $buildFolder\winpe.wim 1 $mountFolder
}
Function WinPE-UnMount($mountFolder){
& $DISM_Path\Imagex.exe /unmount /commit $mountFolder
}
Delete-Folder -folderPath $WinPE_BuildFolder
Delete-Folder -folderPath $WinPE_MountFolder
Make-Directory -folderPath $WinPE_BuildFolder
Make-Directory -folderPath $WinPE_MountFolder
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\en-us\winpe.wim" $WinPE_BuildFolder
# Mount Wim File
WinPE-Mount -buildFolder $WinPE_BuildFolder -mountFolder $WinPE_MountFolder
# Add WinPE 10.0 optional components using ADK 10.0 version of dism.exe
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\$Language\lp.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-Scripting.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\$Language\WinPE-Scripting_$Language.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-WMI.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\$Language\WinPE-WMI_$Language.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-MDAC.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\$Language\WinPE-MDAC_$Language.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-HTA.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\$Language\WinPE-HTA_$Language.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-NetFx.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\$Language\WinPE-NetFx_$Language.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-PowerShell.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\$Language\WinPE-PowerShell_$Language.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\WinPE-DismCmdlets.cab
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Package /PackagePath:$WinPE_OCs_Path\$Language\WinPE-DismCmdlets_$Language.cab
& $DISM_Path\dism.exe /Set-AllIntl:$Language /Image:$WinPE_MountFolder
# Install WinPE 10.0 Drivers
If(Test-Path -Path "$WinPE_Drivers\$WinPE_Architecture"){
& $DISM_Path\dism.exe /Image:$WinPE_MountFolder /Add-Driver /Driver:"$WinPE_Drivers\$WinPE_Architecture" /Recurse /ForceUnsigned
}
# Copy WinPE Application Files
If(Test-Path -Path "$WinPE_AppsFiles\$WinPE_Architecture"){
robocopy "$WinPE_AppsFiles\$WinPE_Architecture\" "$WinPE_MountFolder\Windows\System32\" /e /NDL /NJH /NJS /IS | %{$data = $_.Split([char]9);
if("$($data[4])" -ne "") { $file = "$($data[4])"} ;
Write-Progress "Percentage $($data[0])" -Activity "Copy files..." -CurrentOperation "$($file)" -ErrorAction SilentlyContinue; }
Write-Progress -Activity "Copy files..." -Completed
}
# Unmount folder
WinPE-UnMount -mountFolder $WinPE_MountFolder
Make-Directory -folderPath "$WinPE_BuildFolder\bootiso\Media\sources"
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\$Language\" "$WinPE_BuildFolder\bootiso\Media\$Language" -recurse -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\Boot\Fonts\" "$WinPE_BuildFolder\bootiso\Media\Boot\Fonts" -recurse -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\Boot\$Language\" "$WinPE_BuildFolder\bootiso\Media\Boot\$Language" -recurse -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\Boot\Resources\" "$WinPE_BuildFolder\bootiso\Media\Boot\Resources" -recurse -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\Boot\BCD" "$WinPE_BuildFolder\bootiso\Media\Boot" -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\Boot\boot.sdi" "$WinPE_BuildFolder\bootiso\Media\Boot" -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\Boot\bootfix.bin" "$WinPE_BuildFolder\bootiso\Media\Boot" -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\Boot\memtest.exe" "$WinPE_BuildFolder\bootiso\Media\Boot" -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\EFI\Microsoft\Boot\Fonts" "$WinPE_BuildFolder\bootiso\Media\EFI\Microsoft\Boot\Fonts" -recurse -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\EFI\Microsoft\Boot\Resources" "$WinPE_BuildFolder\bootiso\Media\EFI\Microsoft\Boot\Resources" -recurse -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\EFI\Microsoft\Boot\$Language" "$WinPE_BuildFolder\bootiso\Media\EFI\Microsoft\Boot" -recurse -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\EFI\Microsoft\Boot\Microsoft\Boot\memtest.efi" "$WinPE_BuildFolder\bootiso\Media\EFI\Microsoft\Boot" -recurse -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\EFI\Microsoft\Boot\BCD" "$WinPE_BuildFolder\bootiso\Media\EFI\Microsoft\Boot" -recurse -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\bootmgr" "$WinPE_BuildFolder\bootiso\Media" -Force
Copy-Item "$WinPE_ADK_Path\$WinPE_Architecture\Media\bootmgr.efi" "$WinPE_BuildFolder\bootiso\Media" -Force
Copy-Item "$WinPE_BuildFolder\winpe.wim" "$WinPE_BuildFolder\bootiso\Media\sources\boot.wim" -Force
}
# Make folder to combine two boot.wim files
Function Make-Directory($folderPath){
if (!(Test-Path -path $folderPath)) {New-Item $folderPath -Type Directory}
}
# Modify the BCD store
Function Modify-BCD($bcdFolderPath){
$description = "WinPE10.0_x64"
$a = & "$bcdedit_Path" /store $bcdFolderPath\Boot\BCD /enum
$a2 = $a[15]
$bcdFirstEntry = $a2.split(",")[1].Trim()
if($a[22].Substring(0,14).Trim() -eq "bootmenupolicy"){
$removeMetroStyleEntry = "& '$bcdedit_Path' --% /store $bcdFolderPath\Boot\BCD /deletevalue {default} bootmenupolicy"
Invoke-Expression $removeMetroStyleEntry
}
$commandEditBcdX64 = @"
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} device ramdisk=[boot]\sources\boot_x64.wim,$($bcdFirstEntry)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} osdevice ramdisk=[boot]\sources\boot_x64.wim,$($bcdFirstEntry)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} description $description
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} locale $($Language)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} bootmenupolicy legacy
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} inherit {bootloadersettings}
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} winpe Yes
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} EMS No
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} detecthal Yes
"@
Invoke-Expression $commandEditBcdX64
$b = & 'bcdedit' /store "$bcdFolderPath\Boot\BCD" /copy '{default}' /d "WinPE10.0_x86"
foreach($i in $b){$bcdSecondEntry =$i.Substring(33).split(" ")[0]}
$commandEditBcdx86 = @"
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) device ramdisk=[boot]\sources\boot_x86.wim,$($bcdFirstEntry)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) osdevice ramdisk=[boot]\sources\boot_x86.wim,$($bcdFirstEntry)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) locale $($Language)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) winpe Yes
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) EMS No
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) inherit {bootloadersettings}
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) detecthal Yes
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD -displayorder $($bcdSecondEntry) -addlast
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {bootmgr} locale $($Language)
"@
Invoke-Expression $commandEditBcdx86
}
Function Modify-EFIBCD($bcdFolderPath){
$description = "WinPE10.0_x64"
$a = & "$bcdedit_Path" /store $bcdFolderPath\Boot\BCD /enum
$a2 = $a[16]
$bcdFirstEntry = $a2.split(",")[1].Trim()
if($a[22].Substring(0,14).Trim() -eq "bootmenupolicy"){
$removeMetroStyleEntry = "& '$bcdedit_Path' --% /store $bcdFolderPath\Boot\BCD /deletevalue {default} bootmenupolicy"
Invoke-Expression $removeMetroStyleEntry
}
$commandEditBcdX64 = @"
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} device ramdisk=[boot]\sources\boot_x64.wim,$($bcdFirstEntry)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} osdevice ramdisk=[boot]\sources\boot_x64.wim,$($bcdFirstEntry)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} description $description
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} locale $($Language)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} bootmenupolicy legacy
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} inherit {bootloadersettings}
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} winpe Yes
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} EMS No
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} detecthal Yes
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} path \windows\system32\boot\winload.efi
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {default} isolatedcontext Yes
"@
Invoke-Expression $commandEditBcdX64
$b = & 'bcdedit' /store "$bcdFolderPath\Boot\BCD" /copy '{default}' /d "WinPE10.0_x86"
foreach($i in $b){$bcdSecondEntry =$i.Substring(33).split(" ")[0]}
$commandEditBcdx86 = @"
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) device ramdisk=[boot]\sources\boot_x86.wim,$($bcdFirstEntry)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) osdevice ramdisk=[boot]\sources\boot_x86.wim,$($bcdFirstEntry)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) path \windows\system32\boot\winload.efi
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) isolatedcontext Yes
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) locale $($Language)
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) winpe Yes
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) EMS No
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) inherit {bootloadersettings}
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set $($bcdSecondEntry) detecthal Yes
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD -displayorder $($bcdSecondEntry) -addlast
& "$bcdedit_Path" --% /store $bcdFolderPath\Boot\BCD /set {bootmgr} locale $($Language)
"@
Invoke-Expression $commandEditBcdx86
}
# Create ISO and start Rufus
function CreateISO {
$question = "Create ISO?"
$message = "Press Y to create ISO!"
$choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Yes'))
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&No'))
$decision = $Host.UI.PromptForChoice($question, $message, $choices, 0)
if ($decision -eq 0) {
& $oscdimg_Path "-b$efiboot_Path" "-pEF" "-u1" "-udfver102" "$WinPE_Media" "$WinPE_Folder\$ISOLabel.iso"
StartRufus
}
}
#Start Rufus
function StartRufus {
$question = "Start Rufus?"
$message = "Press Y to start Rufus!"
$choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Yes'))
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&No'))
$decision = $Host.UI.PromptForChoice($question, $message, $choices, 0)
if ($decision -eq 0) {Start-Process "$scriptroot\rufus\rufus-2.8p.exe" -ArgumentList "--gui --iso=$WinPE_Folder\$ISOLabel.iso" -wait}
}
# Delete WinPE_Folder
function DeleteWinPE_Folder {
$question = "Delete '$WinPE_Folder'?"
$message = "Press Y to delete $WinPE_Folder!"
$choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Yes'))
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&No'))
$decision = $Host.UI.PromptForChoice($question, $message, $choices, 1)
if ($decision -eq 0) {
$ListOfFiles = Get-ChildItem -Path $WinPE_Folder -Recurse | Where-Object {!$_.PSIsContainer}
for ($i = 1; $i -lt $ListOfFiles.count; $i++) {
Write-Progress -Activity "Deleting files..." -Status $ListOfFiles[$i].FullName -PercentComplete ($i / ($ListOfFiles.Count*100))
Remove-Item -Recurse -Force -Path $ListOfFiles[$i].FullName
}
Write-Progress -Activity "Deleting files..." -Completed
remove-item $WinPE_Folder -force -recurse
}
}
# Call functions
# To create bootable WinPE x64 - Run this command only
Make-WinPEBootWim -WinPE_Architecture "amd64"
# To create bootable WinPE x 86 - Run this command only
Make-WinPEBootWim -WinPE_Architecture "x86"
# To create DualBoot WinPe x86/x64 - Run above and all the commands below as well
Make-Directory -folderPath $WinPE_Combined
Copy-Item "$amd64\bootiso\Media\*" -Destination $WinPE_Combined -recurse -Force
Copy-Item "$x86\bootiso\Media\EFI\Boot\*" -Destination "$WinPE_Combined\EFI\Boot" -recurse -Force
rename-item -path "$WinPE_Combined\Sources\boot.wim" -newname boot_x86.wim -Force
Copy-Item "$amd64\bootiso\Media\sources\boot.wim" -Destination "$WinPE_Combined\Sources" -Force
rename-item -path "$WinPE_Combined\Sources\boot.wim" -newname boot_x64.wim -Force
rename-item -path $WinPE_Combined -newname $WinPE_Media -Force
Modify-BCD -bcdFolderPath $WinPE_Media
Modify-EFIBCD -bcdFolderPath $EFIbcd
# Copy Programs
robocopy "$scriptroot\addon\usb_root\" "$WinPE_Media" /e /NDL /NJH /NJS | %{$data = $_.Split([char]9);
if("$($data[4])" -ne "") { $file = "$($data[4])"} ;
Write-Progress "Percentage $($data[0])" -Activity "Copy files..." -CurrentOperation "$($file)" -ErrorAction SilentlyContinue; }
Write-Progress -Activity "Copy files..." -Completed
CreateISO
DeleteWinPE_Folder
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment