Adds release notes highlighting improved Surface auto driver matching, more resilient USB driver injection with better logging, and correct Windows index selection for non-English media.
Notes build execution shift to separate PowerShell process for reliable console output, fixes USB selection for identical drive names, and announces new documentation site.
Prevents mobile scroll “fighting” by limiting scrollspy and the page TOC to desktop-sized viewports.
Removes any existing TOC markup and related layout class when below the desktop breakpoint to avoid interfering with touch scrolling.
Prevents long paths, links, and inline code from overflowing into the page TOC.
Stabilizes the two-column layout by defining grid areas, keeping breadcrumbs full-width, and forcing content to respect column width so wide elements don’t render under the TOC.
Improves TOC readability by adding a background and stacking context when content still overflows.
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.
Enhances the driver installation process to be more resilient by allowing non-critical driver injection failures to not halt the entire deployment. Key improvements include:
- Adds `IgnoreExitCode` and `PassThruExitCode` parameters to the process invocation function, enabling callers to handle non-zero exit codes without throwing exceptions.
- Modifies driver injection logic (both WIM and folder-based) to capture exit codes and log warnings instead of failing the deployment when drivers fail to inject.
- Automatically collects and preserves diagnostic logs (dism.log and setupapi.offline.log) to the USB drive when driver installation encounters issues, aiding post-deployment troubleshooting.
- Wraps cleanup operations in try-catch blocks to ensure temporary resources are released even if unmounting or deletion fails.
- Fixes code formatting inconsistencies and indentation throughout the script for improved readability.
This approach prioritizes deployment completion while preserving critical diagnostic information when driver-related issues occur.
Treats driver index cache older than 7 days as stale to trigger re-downloads and avoid outdated metadata.
Improves resiliency by falling back to a refresh when the cache timestamp can’t be read, and adds clearer logging for cache age and refresh decisions.
Reduces unnecessary Download Center requests by preferring cached file details when available
Falls back to downloading/parsing the page only on cache miss, then backfills the cache for future runs
Adds error handling and logging around cache load/update to avoid download failures from cache issues
Adds best-effort Surface System SKU resolution and persists it into driver mappings to reduce model-name ambiguity during deployment.
Speeds up Microsoft model discovery by using a local cache and updates cached Download Center details during driver downloads to keep the UI responsive.
Prefers System SKU-based rule selection for Microsoft devices, falling back to legacy model-string matching when SKU data is unavailable.
Some apps (Camtasia) require dependency apps to be installed first. Winget will download said dependency apps. This commit will place those dependencies before the calling app in the WingetWin32Apps.json file.
Adds post-processing to reorder and re-prioritize winget app entries so install order stays consistent with the configured list, even when parallel downloads append results in completion order.
Serializes updates with a named mutex and writes changes atomically to avoid races and partial writes, with logging around failure cases.
Adds cross-process locking and atomic writes to avoid race conditions and partial writes when multiple runspaces update the app command metadata in parallel.
Improves resilience by backing up and rebuilding when existing JSON is malformed, ensuring the build continues safely.
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.
Documents new features including shared cleanup module, Windows Security
Platform install delay, persistent KB folder for updates, and CU download
skipping when ESD is current.
Fixes WingetWin32Apps.json creation bug for pre-downloaded applications.
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.
Improves disk selection logic to handle systems with multiple fixed disks by prompting the user to choose the target disk when more than one candidate is detected.
Refactors Get-HardDrive to return an array of disk candidates instead of a single disk object with extracted properties, enabling the main script to present options and validate user selection.
Displays disk information in a formatted table showing disk number, size, sector size, bus type, and model to help users make informed decisions.
Validates user input to ensure only available disk numbers can be selected, preventing deployment errors on multi-disk configurations.
Maintains single-disk auto-selection behavior for systems with only one fixed disk, preserving the original user experience for common scenarios.
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.
Adds proper quoting around file paths in the xcopy invocation to support PPKG filenames containing spaces. Without quoted paths, xcopy fails when filenames include whitespace characters.
Introduces a new function to detect and properly quote unquoted MSI file paths in msiexec command arguments. This prevents installation failures when MSI paths contain spaces, as the Windows installer requires quoted paths to correctly parse arguments with whitespace.
The solution uses pattern matching to identify `/i` arguments followed by unquoted `.msi` file paths and automatically wraps them in double quotes. This runs automatically during application installation when msiexec is detected, ensuring reliable installations regardless of path formatting in the configuration.
Updates the tooltip text for application arguments to properly escape quotes around the MSI file path in the example command. This ensures the example is syntactically correct and prevents issues when users copy the suggested format for MSI installations.