Replace the Get-WindowsVersionInfo registry-interrogation step in the VHDX capture path with parameter-driven naming via Get-FFUCaptureNamingInfo. This eliminates the registry load/unload commands and two full minutes of registry sleep time during capture.
By deriving default file and DISM image names from already-resolved target state (WindowsRelease, WindowsVersion, and installationType), capture naming now naturally matches the rest of the script. This also unifies CustomFFUNameTemplate evaluation between live image servicing and cached VHDX reuse instances.
Previously, when a requested Windows SKU was not found in the provided ISO/ESD and the user manually selected a fallback image, the script kept the original (stale) `$WindowsSKU`. This caused downstream features like FFU file naming, VHDX cache metadata, and cumulative update planning to enforce logic against the wrong edition.
- Refactored `Get-Index` into `Get-WindowsImageSelection` to return rich image metadata (including EditionId and InstallationType) instead of just the image index.
- Added `Get-ResolvedWindowsSKUFromImage` to resolve raw image metadata back into the repository's native friendly SKU vocabulary.
- Added `Get-WindowsTargetRuntimeState` to centralize and recalculate dependent variables (`installationType`, `WindowsVersion`, LTSC flags) after the SKU updates mid-flight.
By optimizing and mounting the VHDX directly on the host for image capture, the build process no longer needs to boot the VM into WinPE, create SMB network shares, generate temporary local accounts, or rely on complex Hyper-V switch IP configurations. This streamlines the workflow and eliminates multiple networking and permission-related points of failure.
This change also removes the need to generate and attach WinPE capture media. All related parameters (`ShareName`, `Username`, `VMHostIPAddress`, `CreateCaptureMedia`, `CleanupCaptureISO`), UI controls, capture scripts, and documentation references have been removed or updated to reflect the simplified architecture.
Switches back to utilizing the static cookie for Lenovo PSREF requests, as the token has remained unchanged for months. The dynamic retrieval function call is bypassed to streamline the process but remains in the codebase as a fallback in case the token expires or changes in the future.
Transitions the Microsoft Surface driver model list retrieval to use a centralized Learn-based index. This change unifies the scraping logic between the CLI and UI components, ensuring consistency and simplified maintenance. Cached model lists now serve both interfaces efficiently, reducing unnecessary network requests while retaining fallback mechanisms.
Updates the FFU UI and orchestration scripts to allow users to specify custom file paths for their Bring Your Own (BYO) app lists, rather than forcing the use of `UserAppList.json` in a specific directory.
Also modifies the orchestration to sync this custom path via `AppInstallConfig.json` so that the runtime orchestration phase resolves the correct file name and path during installation. Refreshes the Apps ISO if the custom BYO app list is updated.
Ensures build and cleanup processes run from the expected project location.
Prevents temporary state files from being created or removed in the wrong folder, which avoids stale markers and cleanup failures when launched from the UI or another directory.
Always requests the amd64 products catalog regardless of the target architecture, as it already contains media entries for both x64 and arm64. This removes unnecessary architecture-specific branching.
Improves the current-run cleanup mechanism by tracking file downloads explicitly. This ensures that files downloaded via BITS or preserving older timestamps are correctly identified and removed during cleanup. Extends the run manifest schema to support file backups, allowing for safe restoration of pre-existing scripts and configuration files modified during a run. Additional cleanup logic now correctly prunes residual empty directories after tracked files are removed.
Prevents reusing cached images when the requested disk size changes. Ensures the disk size property is properly saved and verified against existing cache items to maintain configuration accuracy.
Extends the volume optimization helper to safely handle already mounted drives, resolve partition letters, and optionally execute a volume retrim. Replaces inline defragmentation steps with the updated helper prior to caching to ensure a fully compacted and optimized image is stored.
Adds a new configuration parameter and UI toggle to control whether downloaded Windows ESD files are removed after application. Updates the download process to check for and reuse existing ESD files that match the latest metadata filename, saving bandwidth and time on subsequent executions. Integrates the conditional deletion logic into the shared cleanup module.
Adds logic to normalize LTSC/LTSB release years (such as 2016, 2019, 2021, and 2024) to their corresponding base Windows client versions (10 or 11). This ensures correct model retrieval and driver downloading, as OEM catalogs typically evaluate against base Windows versions rather than LTSC-specific release years.
Improves the reliability of locating Windows ADK and WinPE add-on installations.
Updates registry searches to locate installer executables in the bundle cache path instead of relying on display names, avoiding potential mismatches.
Expands the registry queries to check both the WOW6432Node and standard uninstall paths to better support different installation contexts.
Validates the Windows Deployment Tools feature by verifying the existence of expected script files rather than checking the registry.
Adds missing descriptions for cleanup, file copying, and download priority parameters to ensure complete help documentation.
Expands the documented supported values for Windows architectures, releases, and SKUs to accurately reflect expanded capabilities for ARM64, Windows Server, and LTSC deployments.
Corrects minor typos, updates default values to match the current implementation, and reorders parameters alphabetically to improve readability.
Since Windows 10 is out of support and only allows ESU updates, LTSB/LTSC builds are impacted by this and are unable to be offline serviced.
This commit fixes that by installing the CU in the VM, staging the update in a LTSCUpdate folder in the Apps folder.
Always stores .NET MSUs under a dedicated NET folder to keep cache structure consistent across OS variants
Migrates expected legacy root-stored .NET MSUs into the NET folder and prunes stale files from both locations to prevent buildup and mismatches
Prevents update packages for different Windows targets from mixing in a single cache, improving reuse across builds while avoiding DISM picking up stale MSUs.
Keeps pruning, download destinations, and update discovery confined to the OS/version-specific cache, including shared-branch handling for Windows 11 25H2/24H2 and LTSC mappings.
Removes older update packages from the local update cache so servicing tools don’t pick up multiple stale MSUs as sources.
Keeps only the MSUs expected for the current run across Windows, .NET (including LTSC folder layout), and Microcode updates, while logging failures and continuing.
Preserves multiple selected drives that share the same model by storing an array of UniqueIds per model.
Updates drive discovery and UI restore logic to accept either a single UniqueId or a list, preventing missed selections and skipping duplicate additions.
Improves UI responsiveness and interactive behavior by running build/cleanup in a separate PowerShell process instead of background jobs.
Fixes cancellation reliability by terminating the full process tree (including child tools) and using process exit codes for success/failure reporting.
Reduces noisy output by suppressing type-add return values and standardizes cleanup argument passing to avoid switch/boolean binding issues.
Updates selection to match images by language-independent edition metadata instead of localized names, reducing failures across ISO/ESD sources and languages.
Adds server Desktop Experience vs Core handling via installation type and prefers the best match deterministically, falling back to a user prompt only when needed with better logging.
Adds a SUBST-based DISM injection loop to avoid path-length failures when adding large driver sets.
Improves INI/INF parsing reliability with Unicode API settings, a larger auto-growing buffer, and normalization of GUID values.
Hardens driver copying by using long-path prefixes and literal paths, reducing copy errors on deeply nested driver folders.
Fixes buffer truncation in Get-PrivateProfileSection by dynamically
growing the buffer when large INF sections are encountered.
Enhances Copy-Drivers with comprehensive error handling, file existence
checks, and detailed logging for each operation. Adds support for
architecture-specific SourceDisksFiles sections (amd64/arm64) and
provides a summary of matched, skipped, and copied files.
Fixes key-value parsing to handle values containing equals signs.
Extracts ESD metadata resolution into a separate function to enable
version comparison before downloading cumulative updates.
Parses Windows version from both ESD filenames and KB article search
results to determine if the ESD already contains the latest updates,
avoiding redundant downloads and installations.
Improves VHDX cache matching by tracking update names that were skipped
due to version matching, ensuring cached images are correctly reused
when updates are already integrated in the base image.
Adds check to skip downloading updates that already exist locally.
Removes prior behavior of always removing the KB folder. The `$RemoveUpdates` parameter now controls whether the KB folder is removed or not. This change was made due to the size of the Windows 11 CU being > 3-4GB. This will reduce bandwidth, however will require setting `$RemoveUpdates` to true to cleanup old update files.
Removes duplicated KB path cleanup logic scattered across multiple locations in the build script and consolidates it into the shared cleanup module.
Adds KBPath parameter to the cleanup function and handles removal of Windows/.NET cumulative update downloads when RemoveUpdates flag is set.
Improves maintainability by eliminating redundant cleanup code and ensures consistent cleanup behavior across different build scenarios including standard builds, VHDX caching, and restore defaults operations.
Consolidates duplicated cleanup code by moving logic into a shared function, eliminating redundant implementations across multiple locations.
Removes standalone cleanup functions (Remove-FFU, Remove-Apps, Remove-Updates) and replaces scattered cleanup calls with a single invocation of Invoke-FFUPostBuildCleanup.
Enhances driver cleanup to preserve configuration files (Drivers.json and DriverMapping.json) while removing other contents, preventing loss of driver mapping data.
Improves maintainability by centralizing cleanup operations and reducing code duplication, making future updates easier to implement consistently.
Switches from using Invoke-WebRequest to Start-BitsTransferWithRetry for downloading Windows ESD files. This provides better reliability and automatic retry handling for large file downloads.
Also removes trailing blank lines for cleaner formatting.
Moves the `Start-WingetAppDownloadTask` function from the UI module to the common module to enable parallel app downloads in both CLI and UI build paths. This eliminates code duplication and ensures consistent download behavior across build modes.
Updates the `Get-Apps` function to leverage parallel processing instead of sequential iteration, improving performance when downloading multiple applications. Adds support for `LogFilePath` and `ThrottleLimit` parameters to control logging and concurrency.
Introduces a `SkipWin32Json` parameter to differentiate behavior between UI mode (skips JSON generation) and CLI mode (creates JSON for installation). This allows the same download task to work correctly in both contexts.
Updates all callers of `Get-Apps` to pass the new parameters, ensuring proper logging and parallel execution configuration across the build pipeline.
Introduces a new `Threads` parameter that allows users to configure the concurrency level for parallel driver downloads within the script. This parameter defaults to 5, matching the existing UI behavior, and accepts values between 1 and 64 to provide flexible control over resource utilization.
The parameter is now passed to the parallel processing function via the `ThrottleLimit` argument, enabling users to optimize performance based on their system capabilities and network conditions.
Replaces null comparison with count check to properly handle empty arrays. The previous condition would incorrectly pass when the array exists but contains no elements, potentially causing the function to proceed without a valid USB drive.
Switches USB drive matching logic from relying on SerialNumber to using UniqueId, which provides more reliable and consistent device identification across different systems.
Updates the Get-USBDrive function to retrieve UniqueId via Get-Disk and trims the machine name suffix (characters after colon) for consistent matching. The new approach first filters candidates by model and media type, then validates each candidate against the configured UniqueId.
Reflects this change across the UI layer by updating column headers, configuration handling, and drive enumeration functions to use UniqueId instead of SerialNumber for saving and loading USB drive selections.
Introduces a new parameter to control BITS download priority across the build system and UI, allowing users to optimize transfer speeds when needed.
The feature adds a priority selector to the UI with four options (Foreground, High, Normal, Low) and propagates the selection through the build script and common modules. Priority can be set via UI, command-line parameter, or environment variable, with Normal as the default.
Updates the BITS transfer retry logic to respect the configured priority instead of hardcoding Normal priority, and fixes minor code formatting inconsistencies.
Implements manufacturer-specific device identification for automatic driver selection using System SKU, Machine Type, and other vendor identifiers instead of relying solely on model name pattern matching.
Adds normalized manufacturer detection to handle vendor name variations consistently across Dell, HP, Lenovo, and Microsoft Surface devices.
Extracts comprehensive system information from WMI including baseboard details, BIOS metadata, and firmware versions to support accurate device identification and troubleshooting.
Refactors system information gathering into reusable functions that separate data collection from display logic, enabling the driver mapping feature to leverage device identifiers.
Enhances logging by capturing vendor-specific identifiers while hiding internal matching fields from user-facing output to reduce confusion.
Fixes minor log message wording for clarity when driver installation encounters expected failures.
Enhances HP driver handling to properly track and display SystemId alongside ProductName throughout the driver workflow.
Parses SystemId from HP PlatformList.xml and creates unique entries per ProductName/SystemId combination to avoid conflicts when multiple models share the same product name but different system identifiers.
Updates driver lookup and metadata preservation to include SystemId, MachineType, and ProductName fields across download tasks and result processing, ensuring this information persists through JSON import/export operations.
Improves display name generation to show "ProductName (SystemId)" format for HP models when both values are available, providing clearer model identification in the UI and configuration files.
Standardizes driver metadata handling by replacing simple Make lookups with comprehensive driver metadata lookups that preserve all relevant fields for Dell, HP, and Lenovo vendors.
Improves consistency in how driver model names and identifiers are processed for different manufacturers (Microsoft, Dell, HP, Lenovo) throughout the codebase.
Introduces helper functions to extract base names from display names and construct standardized display names with identifiers in parentheses format.
Centralizes the logic for converting driver items to JSON model objects, eliminating code duplication across save and download operations.
Enhances validation during driver import and processing to skip invalid entries with missing required fields like MachineType for Lenovo or empty model names.
Ensures proper parsing of model names containing parenthetical identifiers (e.g., "Product Name (Type)") and extracts components correctly for each vendor's requirements.
Removes obsolete CabRelativePath property from Dell driver handling.
- Implements detailed failure tracking for driver downloads, capturing model names and statuses for failed attempts.
- Updates logging to provide clearer messages for both successful and failed downloads, improving traceability.
- Modifies the user interface to display comprehensive error messages when downloads fail, including a summary of failed models.
- Ensures that all exceptions during download and extraction processes are logged and thrown, preventing silent failures.