Add configurable FFU build partition drive letters

Add System, Windows, and Recovery partition drive-letter settings to the Hyper-V Settings UI, config save/load, BuildFFUVM parameters, and sample/docs. Defaults remain S, W, and R.

Validate selected letters early, log validation failures for the UI, include drive-letter metadata in VHDX cache matching, and normalize legacy malformed cache values. This only affects FFU build-time partitioning; ApplyFFU deployment letters remain unchanged.
This commit is contained in:
rbalsleyMSFT
2026-06-05 09:46:00 -07:00
parent c32cb93434
commit 9fb9e81701
10 changed files with 262 additions and 21 deletions
+24 -10
View File
@@ -338,7 +338,6 @@ $script:uiState.Controls.btnRun.Add_Click({
$script:uiState.Flags.isCleanupRunning = $true
$script:uiState.Data.pollTimer.Add_Tick({
param($sender, $e)
$currentProcess = $script:uiState.Data.currentBuildProcess
# Read new lines from log
@@ -353,13 +352,13 @@ $script:uiState.Controls.btnRun.Add_Click({
}
if ($null -eq $currentProcess -or $null -eq $script:uiState.Data.pollTimer) {
if ($null -ne $sender) { $sender.Stop() }
if ($null -ne $script:uiState.Data.pollTimer) { $script:uiState.Data.pollTimer.Stop() }
$script:uiState.Data.pollTimer = $null
return
}
if ($currentProcess.HasExited) {
if ($null -ne $sender) { $sender.Stop() }
if ($null -ne $script:uiState.Data.pollTimer) { $script:uiState.Data.pollTimer.Stop() }
$script:uiState.Data.pollTimer = $null
if ($null -ne $script:uiState.Data.logStreamReader) {
@@ -621,7 +620,6 @@ $script:uiState.Controls.btnRun.Add_Click({
# Add the Tick event handler
$script:uiState.Data.pollTimer.Add_Tick({
param($sender, $e)
# This scriptblock runs on the UI thread, so it can safely access script-scoped variables
$currentProcess = $script:uiState.Data.currentBuildProcess
@@ -649,8 +647,8 @@ $script:uiState.Controls.btnRun.Add_Click({
# If process is somehow null or the timer has been nulled out, stop the timer
if ($null -eq $currentProcess -or $null -eq $script:uiState.Data.pollTimer) {
if ($null -ne $sender) {
$sender.Stop()
if ($null -ne $script:uiState.Data.pollTimer) {
$script:uiState.Data.pollTimer.Stop()
}
$script:uiState.Data.pollTimer = $null
return
@@ -659,8 +657,8 @@ $script:uiState.Controls.btnRun.Add_Click({
# Check if the build process has exited
if ($currentProcess.HasExited) {
# Stop the timer, we're done polling
if ($null -ne $sender) {
$sender.Stop()
if ($null -ne $script:uiState.Data.pollTimer) {
$script:uiState.Data.pollTimer.Stop()
}
$script:uiState.Data.pollTimer = $null
@@ -698,9 +696,25 @@ $script:uiState.Controls.btnRun.Add_Click({
# Determine final status based on process exit code
$finalStatusText = "FFU build completed successfully."
if ($exitCode -ne 0) {
$finalStatusText = "FFU build failed. Check FFUDevelopment.log for details."
$failureDetail = $null
if ($null -ne $script:uiState.Data.logData) {
for ($logIndex = $script:uiState.Data.logData.Count - 1; $logIndex -ge 0; $logIndex--) {
$logLine = [string]$script:uiState.Data.logData[$logIndex]
if ($logLine -match '(?i)(Build validation failed|Exception|ERROR|already assigned|must be a single drive letter|must be unique)') {
$failureDetail = $logLine
break
}
}
}
$finalStatusText = if ($failureDetail) { "FFU build failed. $failureDetail" } else { "FFU build failed. Check FFUDevelopment.log for details." }
WriteLog "BuildFFUVM.ps1 process failed with exit code: $exitCode"
[System.Windows.MessageBox]::Show("The build process failed. Please check the $FFUDevelopmentPath\FFUDevelopment.log file for details.`n`nExit code: $exitCode", "Build Error", "OK", "Error") | Out-Null
$buildErrorMessage = "The build process failed. Please check the $FFUDevelopmentPath\FFUDevelopment.log file for details."
if ($failureDetail) {
$buildErrorMessage += "`n`n$failureDetail"
}
$buildErrorMessage += "`n`nExit code: $exitCode"
[System.Windows.MessageBox]::Show($buildErrorMessage, "Build Error", "OK", "Error") | Out-Null
$script:uiState.Controls.pbOverallProgress.Visibility = 'Collapsed'
}
else {