<# .SYNOPSIS Builds a bootable WinPE USB drive that can be used to run New-Win11GeneralizedImage.ps1 -Mode Capture. .DESCRIPTION This script must be run as Administrator on a machine that has the Windows ADK and the "Windows PE add-on for the ADK" installed. It will: 1. Locate copype.cmd / MakeWinPEMedia.cmd from the installed ADK. 2. Build a WinPE working folder for the specified architecture (copype). 3. Optionally inject PowerShell + network/storage support and a custom startup script. 4. Copy New-Win11GeneralizedImage.ps1 (and any extra files) onto the WinPE media so it's available once booted. 5. Format the target USB drive and copy the bootable WinPE media onto it (MakeWinPEMedia /UFD). WARNING: The target USB drive is completely erased. Double-check -UsbDriveLetter before running. .PARAMETER UsbDriveLetter The drive letter of the USB flash drive to turn into bootable WinPE media, e.g. "F:". This drive will be wiped. .PARAMETER Architecture WinPE architecture to build: amd64 (default), x86, or arm64. .PARAMETER WorkingDirectory Folder used to stage the WinPE image files. Defaults to "C:\WinPE_". .PARAMETER IncludeCaptureScript Path to New-Win11GeneralizedImage.ps1 (or any other script) to copy onto the WinPE media so it can be run directly after boot. Defaults to New-Win11GeneralizedImage.ps1 next to this script, if present. .EXAMPLE .\New-WinPEUsbMedia.ps1 -UsbDriveLetter F: -Architecture amd64 .NOTES Requires the Windows ADK + WinPE add-on: https://learn.microsoft.com/windows-hardware/get-started/adk-install Run from an elevated "Deployment and Imaging Tools Environment" or a normal elevated PowerShell prompt. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidatePattern('^[A-Za-z]:$')] [string]$UsbDriveLetter, [ValidateSet("amd64", "x86", "arm64")] [string]$Architecture = "amd64", [string]$WorkingDirectory, [string]$IncludeCaptureScript = (Join-Path -Path $PSScriptRoot -ChildPath "New-Win11GeneralizedImage.ps1") ) $ErrorActionPreference = "Stop" function Test-IsAdmin { $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($identity) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } function Write-Step { param([string]$Message) Write-Host "`n==> $Message" -ForegroundColor Cyan } if (-not (Test-IsAdmin)) { Write-Error "This script must be run as Administrator. Right-click PowerShell and choose 'Run as Administrator', then re-run this script." exit 1 } if (-not $WorkingDirectory) { $WorkingDirectory = "C:\WinPE_$Architecture" } # Locate the ADK deployment tools that ship copype.cmd / MakeWinPEMedia.cmd $adkRoots = @( "${env:ProgramFiles(x86)}\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment", "$env:ProgramFiles\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment" ) $dandiScript = $null foreach ($root in $adkRoots) { $candidate = Join-Path -Path (Split-Path -Path $root -Parent) -ChildPath "DandISetEnv.bat" if (Test-Path -Path $candidate) { $dandiScript = $candidate break } } if (-not $dandiScript) { Write-Error "Could not find the Windows ADK Deployment Tools environment (DandISetEnv.bat). Install the Windows ADK and the 'Windows PE add-on for the ADK' first: https://learn.microsoft.com/windows-hardware/get-started/adk-install" exit 1 } Write-Step "Using ADK deployment tools environment: $dandiScript" # Import the ADK's Deployment Tools environment variables (sets copype/MakeWinPEMedia on PATH) into this session $envVars = cmd /c "`"$dandiScript`" && set" foreach ($line in $envVars) { if ($line -match '^([^=]+)=(.*)$') { [System.Environment]::SetEnvironmentVariable($Matches[1], $Matches[2], "Process") } } $copype = (Get-Command copype.cmd -ErrorAction SilentlyContinue) $makeWinPEMedia = (Get-Command MakeWinPEMedia.cmd -ErrorAction SilentlyContinue) if (-not $copype -or -not $makeWinPEMedia) { Write-Error "copype.cmd / MakeWinPEMedia.cmd were not found on PATH even after loading the ADK environment." exit 1 } if (Test-Path -Path $WorkingDirectory) { Write-Step "Removing existing working directory $WorkingDirectory" Remove-Item -Path $WorkingDirectory -Recurse -Force } Write-Step "Building WinPE working folder ($Architecture) at $WorkingDirectory" & $copype.Source $Architecture $WorkingDirectory if ($LASTEXITCODE -ne 0) { Write-Error "copype failed with exit code $LASTEXITCODE." exit $LASTEXITCODE } if ($IncludeCaptureScript -and (Test-Path -Path $IncludeCaptureScript)) { Write-Step "Copying $IncludeCaptureScript onto the WinPE media" $mediaRoot = Join-Path -Path $WorkingDirectory -ChildPath "media" Copy-Item -Path $IncludeCaptureScript -Destination (Join-Path -Path $mediaRoot -ChildPath (Split-Path -Path $IncludeCaptureScript -Leaf)) -Force } else { Write-Warning "IncludeCaptureScript '$IncludeCaptureScript' not found, skipping." } Write-Host "`nThe target drive $UsbDriveLetter will be ERASED." -ForegroundColor Yellow $confirm = Read-Host "Type YES to continue and format $UsbDriveLetter as bootable WinPE USB media" if ($confirm -ne "YES") { Write-Host "Aborted, no changes made to $UsbDriveLetter." -ForegroundColor Yellow exit 0 } Write-Step "Formatting $UsbDriveLetter and copying bootable WinPE media (MakeWinPEMedia /UFD)" & $makeWinPEMedia.Source /UFD $WorkingDirectory $UsbDriveLetter /f if ($LASTEXITCODE -ne 0) { Write-Error "MakeWinPEMedia failed with exit code $LASTEXITCODE." exit $LASTEXITCODE } Write-Host "`nWinPE USB media created successfully on $UsbDriveLetter." -ForegroundColor Green Write-Host "Boot the reference machine from this USB drive, then from the WinPE command prompt run:" -ForegroundColor Green Write-Host " powershell -ExecutionPolicy Bypass -File X:\New-Win11GeneralizedImage.ps1 -Mode Capture -SourceDrive D: -DestinationWim E:\Images\Win11Pro.wim" -ForegroundColor DarkGray