149 lines
6.1 KiB
PowerShell
149 lines
6.1 KiB
PowerShell
<#
|
|
.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_<Architecture>".
|
|
|
|
.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
|