Adds a new function to gather and display detailed system information (model, CPU, memory, disk size) in both the log file and the console. This helps with verification and troubleshooting.
Improves the user experience by adding an ASCII art banner and cleaning up the console output by suppressing progress bars and command echoes.
Modernizes the script by replacing the deprecated `Get-WmiObject` cmdlet with `Get-CimInstance`.
Pipes the FFU selection table through `Out-String` to ensure it is correctly rendered in the console. This prevents potential issues where the formatted table object is not displayed as intended.
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.
Sets the verbose preference within the `FFU.Common` module to match the preference of the calling script.
This ensures that when the script is run with the `-Verbose` switch, verbose output from the module is also logged to the console.
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.
Refines the driver selection logic to correctly handle overlapping or wildcard-based rules in the driver mapping file.
Previously, the script would use the first rule that matched the system manufacturer and model. This could lead to a less specific rule being chosen if it appeared before a more specific one.
The logic now finds all matching rules and selects the one with the most specific model name, ensuring a more accurate driver package is applied.
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.
Streamlines the driver discovery process by searching for both WIM files and driver folders at the same time. This replaces the previous sequential logic that checked for WIMs first, then folders.
If multiple driver sources are found, they are now presented in a single, unified list for user selection, regardless of whether they are a WIM or a folder. This simplifies the script's control flow and improves the user experience.
Updates the driver installation logic to prioritize searching for and installing drivers from .wim files located in the `Drivers` directory. If a single WIM is found, it is used automatically. If multiple WIMs are found, the user is prompted for a selection.
The script extracts the WIM to a temporary location before injecting the drivers. The previous method of installing from a folder is retained as a fallback if no WIM files are present. Error handling and cleanup for the WIM installation process are also included.
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.
Removes the logic for managing the visibility of Office installation options from the window's loaded event handler.
This change centralizes UI state management within dedicated event handlers, simplifying the initial UI setup.
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.
Moves the interdependent state logic for the driver-related checkboxes from the main UI script into a new, centralized function within the core module.
This change simplifies the event handling by using a single handler for all related checkboxes, which improves code readability and maintainability. The new function is also called during initialization to ensure the UI reflects the correct state on startup.
Moves the 'Browse' button click event handlers from the main UI script into the core handlers module.
This change improves code organization and separation of concerns. The handlers are updated to be more self-contained by retrieving state from the event source rather than relying on a global state variable, which improves modularity.
Moves the event handling and business logic for the "Bring Your Own Applications" feature from the main UI script into dedicated core modules.
This change improves code organization and separation of concerns by centralizing application-related functions and their corresponding event handlers. The main UI script is now cleaner and primarily responsible for UI initialization, enhancing overall code maintainability.
Extracts the Winget app download logic from the main UI script into a new `Invoke-WingetDownload` function within the core Winget module.
This change decouples the UI event handling from the business logic, improving modularity and maintainability. It also introduces more robust error handling for the download process by wrapping the logic in a try/catch block.
Moves UI event handling logic from the main script into a dedicated core module to improve separation of concerns.
Introduces a new shared function, `Clear-ListViewContent`, to consolidate duplicated logic for clearing list views. This generic function handles user confirmation, data source clearing, and UI updates for multiple tabs, significantly reducing code redundancy.
Relocates the event handling logic for the "Applications" tab from the main UI script into the `FFUUI.Core.Handlers` module.
This improves code organization and modularity by centralizing UI logic. The handlers are also updated to use local state instead of a global variable.
Moves event handlers and initial state configuration for the USB drive creation settings from the main UI script into the core handler and initialization modules.
This change centralizes the UI logic, improving code organization and maintainability.
Refactors the package search logic to process results as a stream instead of collecting them all in memory first.
This change uses the PowerShell pipeline to transform search results on the fly. This significantly reduces memory usage and improves responsiveness, especially for queries that return a large number of packages.
Updates the USB drive selection UI to align with other list views in the application. This change replaces the static "Select All" checkbox with a dynamic, selectable column that includes the checkbox in the header.
This refactoring provides a more consistent user experience and adds column sorting functionality to the USB drive list.
Additionally, the underlying shared function for creating selectable columns is improved to use the central UI state object for managing controls, removing the dependency on script-scoped variables for better encapsulation.
Moves the event handling logic for the USB drive selection controls from the main UI script to the `FFUUI.Core.Handlers` module.
This change improves code organization by centralizing UI logic. The handlers were also improved to correctly manage the "Select All" checkbox state.
Moves the click event handler for detecting USB drives from the main UI script to the dedicated core handlers module.
This change centralizes UI logic, improving code organization and maintainability.
Moves the event handling logic for the "Latest CU" and "Preview CU" checkboxes from the main UI script into the core handlers module.
This change centralizes UI event handling, improving code organization and maintainability. The new implementation is also more robust, accessing state via the window's `Tag` property rather than a global script variable.