Adds a new function to programmatically retrieve the required authentication token for the Lenovo PSREF API. This change is necessary as Lenovo is now restricting API access without a JavaScript-generated token.
The new function launches a headless browser instance, uses the DevTools protocol to extract the token from local storage, and then terminates the browser. This ensures continued access to the comprehensive model data available through the PSREF API, which is not fully present in other catalogs.
The User-Agent string has also been updated.
Refactors the application download logic to correctly handle packages from the 'msstore' source, which does not support architecture specification.
- The download process no longer passes an architecture parameter for msstore apps.
- The architecture selection dropdown in the UI is now disabled for msstore apps to prevent invalid configurations.
- Imported or searched msstore apps will display 'NA' for their architecture.
Refactors the Store app installation script to be significantly more robust and intelligent. The new implementation automatically resolves application dependencies instead of relying on a simple folder structure.
Key improvements include:
- Pre-scans all application folders to create a central catalog of available dependencies.
- Parses the `AppxManifest.xml` from each main app package (including from within bundles) to determine its true dependencies.
- Resolves the required dependencies by finding the best available package from the catalog that meets version and OS architecture requirements.
- Adds support for extracting zipped dependency packages.
- Improves temporary file management and logging.
Refactors the Winget search functionality to enhance performance and provide a better user experience.
- Updates the UI to show a wait cursor, disable the search button, and display a status message during the search operation.
- Improves the post-search status message to differentiate between new and total applications found.
- Utilizes `ForEach-Object -Parallel` to speed up the processing of search results on multi-core systems.
Removes the log message that is generated when auto-scrolling is enabled. This reduces log spam, as this can be a frequent event.
The message for when a user manually disables auto-scrolling is retained.
Improves the reliability and clarity of the application download process.
- Introduces specific error codes for download failures, such as publisher restrictions from the Microsoft Store.
- Blocks downloading the Company Portal app from the `winget` source due to packaging issues and provides a user-friendly message.
- Refines status messages in the UI for better user feedback.
- Installs the WinGet PowerShell module for all users to prevent context-related issues.
Improves the pre-download check to correctly identify existing multi-architecture applications by looking for both x86 and x64 subfolders.
This prevents unnecessary re-downloads of apps that have separate builds for each architecture. The logic is also consolidated to remove a redundant code block.
Introduces the ability to specify and download multiple architectures for a single application.
- Adds an "Architecture" dropdown column to the Winget UI, allowing users to select the desired architecture(s) for each app (e.g., x86, x64, arm64, or 'x86 x64').
- Updates the download logic to process each specified architecture, creating separate subfolders for multi-architecture Win32 apps.
- Modifies the app list format to save and load the selected architecture for each application.
- Improves the download process by checking if an application has already been downloaded before attempting a new download.
Removes the use of global variables for paths and architecture settings. Instead, these values are now passed explicitly as parameters to the relevant functions.
This change improves code clarity, reduces the risk of side effects, and makes the functions more modular and easier to test.
Adds standard PowerShell comment-based help blocks (synopsis and description) to all UI and common library script modules (`.psm1`) and the main UI entry point script (`.ps1`).
This improves maintainability and discoverability by documenting the purpose of each script file. Also removes various redundant or commented-out code blocks.
Adds a "Threads" setting to the UI, allowing users to control the throttle limit for parallel tasks like driver and application processing.
This introduces a new textbox in the build options and updates the parallel processing function to use this configurable value instead of a hardcoded one.
Input validation is also added to ensure the threads value is a valid integer and is at least 1. The new setting is integrated into the configuration save/load functionality.
Adds a validation check to ensure application names are unique.
If a user attempts to add an application with a name that already exists, a warning message is displayed, and the operation is cancelled.
Prevents stale, intermediate status messages from overwriting the final status of a completed task in the UI.
A set of completed task identifiers is now maintained. Any incoming intermediate status updates for tasks that are already marked as complete are ignored.
The job completion logic is also refactored for better robustness and clarity across different job-end states (failed, completed with data, completed without data).
Improves the "Copy BYO Apps" functionality by centralizing the `UserAppList.json` update process. The application list is now saved once from the UI before starting the copy, rather than individually within each background task.
Adds a confirmation prompt that warns the user if any application folders already exist in the destination, allowing them to choose whether to overwrite them. The copy logic is updated to remove existing folders before copying to ensure a clean state.
Enhances the orchestrator script to skip application installation steps if no corresponding app lists or files are present. This prevents unnecessary script executions and cleans up the output log.
Makes the 'Arguments' field optional when adding a 'Bring Your Own' application, simplifying the process for apps without arguments.
Ensures the 'Priority' field for applications is consistently saved as an integer to improve data integrity.
Implements the click handler for the browse button associated with the Office configuration XML file path.
This change enables users to select the configuration file via a file dialog, automatically populating the path into the text field and improving usability.
Refines the logic for setting the Windows Release from a saved configuration to handle ambiguous values.
When a release value like '2019' exists for both Server and LTSC editions, the UI could select the wrong item. The logic now inspects the `WindowsSKU` config value to differentiate between them, correctly selecting the LTSC or non-LTSC release.
Improves the user experience in the monitor tab by making the log output autoscroll conditional.
Autoscrolling is now disabled when the user selects a log entry other than the last one, allowing them to inspect previous output without interruption. Selecting the last item in the list re-enables autoscrolling.
Adds a feature to automatically save the selected drivers to `Drivers.json` upon download, preserving the user's selection for future use.
Improves script execution by:
- Ensuring the disk cleanup process completes before proceeding.
- Suppressing progress bars globally for a cleaner console output.
- Hiding non-critical warnings during driver installation.
- Removing an unused BITS transfer function and trailing whitespace.
Introduces a new "Monitor" tab in the `BuildFFUVM` UI to display live log output from the build process.
When a build is started, the UI now automatically switches to the Monitor tab. It tails the main log file in real-time and displays the content in a list view, which auto-scrolls as new entries appear.
This provides immediate visual feedback on the build progress and any errors without needing to manually open the log file.
Additionally, this change adds a Ctrl+C keyboard shortcut to copy selected log lines from the monitor view to the clipboard.
Updates the UI to conditionally hide the Windows language and media type controls. These settings are only applicable when downloading a new image and are irrelevant when a local ISO file is provided.
This change simplifies the user interface and prevents confusion by only showing options relevant to the selected action.
Inverts the conditional logic for determining available Windows releases and versions based on whether an ISO path is provided.
This change improves code readability by checking for the positive case (an ISO is present) first. It also adds validation to ensure the file path ends with the `.iso` extension.
Implements logic to filter the available Windows architectures based on the selected OS Release, Version, and SKU. This ensures that only valid architecture options are presented to the user.
- Adds a new function to determine the correct architectures for different Windows versions (e.g., Server, Windows 10/11, LTSC editions).
- Wires up event handlers to the Release, Version, and SKU dropdowns to refresh the architecture list when their selection changes.
- Refactors initialization to use this new dynamic logic.
This helps in troubleshooting the FFU build process by providing more detailed output to the console. The verbose setting is saved to and loaded from the configuration file.
Removes the logic that adds a `Success` property to the returned object when an existing driver package is found.
This property is handled by the calling function, making this assignment unnecessary and simplifying the driver-saving task functions.
Implements logic to compress previously downloaded driver folders into WIM files if the compression option is enabled. This ensures consistency in the driver store when re-running the download process.
Refactors the parallel task processing to rely on a standardized boolean 'Success' property from all driver download tasks. This simplifies the result handling logic and makes it more reliable than parsing status strings.
Adds a new `Test-ExistingDriver` function to the common driver module to centralize the logic for checking if drivers have already been downloaded, either as a folder or a WIM file.
This change removes duplicated code from the Dell, HP, Lenovo, and Microsoft driver download tasks, simplifying maintenance and ensuring consistent behavior across all manufacturers.
Refactors the driver download logic for all manufacturers to first check for the existence of a final `.wim` archive. If a WIM file is found, the download and processing for that model is skipped, significantly improving performance on subsequent runs.
This change also resolves a potential type conversion error when processing driver mapping JSON files and corrects a minor typo in a log message.
Removes the parameter for installing preview cumulative updates to simplify the script's interface.
Improves logging during the driver copy process to provide better visibility into which drivers are being used.
The UI no longer loads the selected device 'Make' from the configuration on startup.
Enhances the modern folder browser to accept and open to a specified initial directory.
This improves the user experience by starting the "Browse for Drivers" dialog in the project's 'Drivers' subfolder, reducing the need for manual navigation. The implementation uses the Win32 API to create a shell item from the initial path and set it as the dialog's starting folder.
Automatically deletes the source driver folder after successful compression into a WIM file to conserve disk space. A failure to delete will only log a warning and not interrupt the process.
Removes unused 'Make' and 'Model' properties from the UI configuration.
Adds a `DriverMapping.json` file to automate driver injection during image deployment.
Driver download tasks now generate or update this mapping file with the relative path for each successfully downloaded driver package.
The deployment script now uses this file to automatically detect and select the correct drivers for the target hardware, removing the need for manual selection. The manual driver selection prompt is retained as a fallback.
Implements a dedicated mutex to serialize MSI extraction operations. This prevents race conditions when multiple driver packages are processed in parallel by different tasks.
Adds a post-extraction verification step to ensure the target directory is not empty. This guards against silent failures where `msiexec` exits successfully but extracts no files, triggering a retry if necessary.
Modifies the item lookup logic to query the `ItemsSource` property instead of the `Items` collection.
This ensures changes are applied directly to the underlying data source, leading to more reliable UI updates.
Updates the download function to source selected drivers from the complete data model instead of the UI's filtered view.
This corrects an issue where selected drivers would be excluded from the download operation if they were hidden by a filter.
Refactors the Dell driver catalog parsing to use a streaming `System.Xml.XmlReader` instead of loading the entire XML file into memory.
This change significantly reduces the memory footprint and improves performance, especially when processing large catalog files. The new approach reads the file node by node, processing each software component individually.
Moves the Dell catalog download and preparation logic from the individual driver download task to the parent function.
This prevents a race condition where multiple parallel tasks would attempt to download and extract the same catalog file simultaneously. The catalog is now prepared once before any driver downloads begin, improving efficiency and reliability.
Additionally, comments out manual garbage collection calls in the VM build UI.
Moves the logic for saving and loading configuration files from the main UI script into the `FFUUI.Core.Config` module. This change improves modularity and separation of concerns, making the code easier to maintain.
The main `BuildFFUVM_UI.ps1` script is simplified, with event handlers now calling the new, dedicated functions in the core module to manage configuration state.
Also corrects the path for the `FFUConfig.json` file.
Extracts the driver download implementation from the button click event handler into a new `Invoke-DownloadSelectedDrivers` function.
This change improves code modularity and maintainability by separating the business logic for downloading drivers from the UI event handling code. The event handler is now simplified to a single function call.
Extracts the model fetching and UI update logic from the button's click event handler into a new, reusable `Invoke-GetModels` function.
This refactoring improves code organization by separating UI event handling from the core application logic, leading to better readability and maintainability.
Extracts the logic for toggling an item's selection state with the spacebar into a new, reusable function. This change centralizes previously duplicated code, improving maintainability.
The event handling is moved from `KeyDown` to `PreviewKeyDown` to provide a more reliable user experience. Additionally, focus is now correctly restored to the toggled item, preventing the selection from moving unexpectedly.
Introduces a new `Invoke-BrowseAction` helper function to consolidate the creation of file and folder selection dialogs.
This change replaces scattered and repetitive `OpenFileDialog`, `SaveFileDialog`, and `ModernFolderPicker` implementations throughout the event handlers with a single, unified function call. This refactoring simplifies the event handler code, reduces duplication, and improves maintainability.
Move the `Initialize-VMSwitchData` function call from the main UI script into the `Initialize-UIDefaults` function.
This change centralizes the UI default initialization logic within the core module, improving code organization and ensuring VM Switch data is loaded at the correct time.
Moves UI initialization logic for the "Bring Your Own" applications section from the main UI script into the `FFUUI.Core` module.
This centralization cleans up the main script's `Loaded` event handler and improves code organization and maintainability.
Consolidates the scattered event handlers for the Applications tab checkboxes into a single, centralized function and a shared event handler. This new approach manages the visibility of all dependent UI panels based on the state of the checkboxes.
This refactoring simplifies the codebase, eliminates redundant logic, and ensures a more consistent and predictable user interface state.
Additionally, this change fixes bugs where clearing list views for Winget results and drivers did not properly update their "select all" header checkboxes.
Moves the initial state logic for the "Latest CU" and "Preview CU" checkboxes from the main UI script to the core initialization module.
This change centralizes UI default settings into the `Initialize-UIDefaults` function, improving code organization and maintainability.
Consolidates the logic for showing and hiding UI elements into dedicated functions, `Update-DriverDownloadPanelVisibility` and `Update-OfficePanelVisibility`.
This change simplifies the event handlers for the "Download Drivers" checkbox by using a single handler for both checked and unchecked states. It also moves the initial UI setup from the main script into the core initialization module, improving code organization and reducing duplication.
Extracts inline event handler logic for managing Apps Script Variables from the main UI script into new functions within the `FFUUI.Core.Applications` module.
This change improves code organization and maintainability by centralizing the logic for adding and removing variables. The event handlers are updated to call these new, dedicated functions.