Added new $state object and refactored code to use the $state reference instead.

- Moved Get-UIConfig from BuildFFUVM_UI.ps1 to FFUUI.Core.psm1 to enhance separation of concerns.
- Updated Get-UIConfig to accept a central $State object, removing direct dependencies on global UI variables.
- Modified internal logic to access UI control values from the $State.Controls hashtable.
- Updated calls in BuildFFUVM_UI.ps1 to pass the $script:uiState object to the refactored function.
- Exported Get-UIConfig from FFUUI.Core.psm1 for accessibility in the main UI script.
This commit is contained in:
rbalsleyMSFT
2025-06-07 17:36:30 -07:00
parent 1b5fa5129c
commit 11084f6689
4 changed files with 917 additions and 846 deletions
+2 -2
View File
@@ -4316,7 +4316,7 @@ if ($InstallApps) {
if (-Not $MSRTDownloaded) { if (-Not $MSRTDownloaded) {
# Create the search string for MSRT based on Windows architecture and release # Create the search string for MSRT based on Windows architecture and release
if ($WindowsArch -eq 'x64') { if ($WindowsArch -eq 'x64') {
if ($installationType -eq 'client' -and $isLTSC -eq $false) { if ($installationType -eq 'client' -and (-not $isLTSC)) {
$Name = """Windows Malicious Software Removal Tool x64""" + " " + """Windows $WindowsRelease""" $Name = """Windows Malicious Software Removal Tool x64""" + " " + """Windows $WindowsRelease"""
} }
# Handle LTSB/LTSC # Handle LTSB/LTSC
@@ -4339,7 +4339,7 @@ if ($InstallApps) {
WriteLog "Creating $MSRTPath" WriteLog "Creating $MSRTPath"
New-Item -Path $MSRTPath -ItemType Directory -Force | Out-Null New-Item -Path $MSRTPath -ItemType Directory -Force | Out-Null
} }
WriteLog "Searching for $Name from Microsoft Update Catalog and saving to $MSRTPath"
WriteLog "Getting Windows Malicious Software Removal Tool URL" WriteLog "Getting Windows Malicious Software Removal Tool URL"
$MSRTFileName = Save-KB -Name $Name -Path $MSRTPath $MSRTFileName = Save-KB -Name $Name -Path $MSRTPath
WriteLog "Latest Windows Malicious Software Removal Tool saved to $MSRTPath\$MSRTFileName" WriteLog "Latest Windows Malicious Software Removal Tool saved to $MSRTPath\$MSRTFileName"
File diff suppressed because it is too large Load Diff
+141 -26
View File
@@ -371,12 +371,12 @@ function Get-AvailableSkusForRelease {
} }
} }
# Function to return general default settings for various UI elements (Moved from UI_Helpers) # Function to return general default settings for various UI elements
function Get-GeneralDefaults { function Get-GeneralDefaults {
[CmdletBinding()] [CmdletBinding()]
param( param(
[Parameter(Mandatory)] [Parameter(Mandatory)]
[string]$FFUDevelopmentPath # Base path needed to derive other paths [string]$FFUDevelopmentPath
) )
# Derive paths based on the main development path # Derive paths based on the main development path
@@ -387,6 +387,7 @@ function Get-GeneralDefaults {
$ffuCapturePath = Join-Path -Path $FFUDevelopmentPath -ChildPath "FFU" $ffuCapturePath = Join-Path -Path $FFUDevelopmentPath -ChildPath "FFU"
$officePath = Join-Path -Path $appsPath -ChildPath "Office" $officePath = Join-Path -Path $appsPath -ChildPath "Office"
$appListJsonPath = Join-Path -Path $appsPath -ChildPath "AppList.json" $appListJsonPath = Join-Path -Path $appsPath -ChildPath "AppList.json"
$driversJsonPath = Join-Path -Path $driversPath -ChildPath "Drivers.json"
return [PSCustomObject]@{ return [PSCustomObject]@{
# Build Tab Defaults # Build Tab Defaults
@@ -395,26 +396,26 @@ function Get-GeneralDefaults {
ShareName = "FFUCaptureShare" ShareName = "FFUCaptureShare"
Username = "ffu_user" Username = "ffu_user"
BuildUSBDriveEnable = $false BuildUSBDriveEnable = $false
CompactOS = $false CompactOS = $true
Optimize = $false Optimize = $true
AllowVHDXCaching = $false AllowVHDXCaching = $false
CreateCaptureMedia = $false CreateCaptureMedia = $true
CreateDeploymentMedia = $false CreateDeploymentMedia = $true
AllowExternalHardDiskMedia = $false AllowExternalHardDiskMedia = $false
PromptExternalHardDiskMedia = $false PromptExternalHardDiskMedia = $true
SelectSpecificUSBDrives = $false SelectSpecificUSBDrives = $false
CopyAutopilot = $false # New CopyAutopilot = $false
CopyUnattend = $false # New CopyUnattend = $false
CopyPPKG = $false # New CopyPPKG = $false
CleanupAppsISO = $false CleanupAppsISO = $true
CleanupCaptureISO = $false CleanupCaptureISO = $true
CleanupDeployISO = $false CleanupDeployISO = $true
CleanupDrivers = $false CleanupDrivers = $false
RemoveFFU = $false RemoveFFU = $false
RemoveApps = $false RemoveApps = $false
RemoveUpdates = $false RemoveUpdates = $false
# Hyper-V Settings Defaults # Hyper-V Settings Defaults
VMHostIPAddress = "" # Requires user input VMHostIPAddress = ""
DiskSizeGB = 30 DiskSizeGB = 30
MemoryGB = 4 MemoryGB = 4
Processors = 4 Processors = 4
@@ -422,13 +423,13 @@ function Get-GeneralDefaults {
VMNamePrefix = "_FFU" VMNamePrefix = "_FFU"
LogicalSectorSize = 512 LogicalSectorSize = 512
# Updates Tab Defaults # Updates Tab Defaults
UpdateLatestCU = $false UpdateLatestCU = $true
UpdateLatestNet = $false UpdateLatestNet = $true
UpdateLatestDefender = $false UpdateLatestDefender = $true
UpdateEdge = $false UpdateEdge = $true
UpdateOneDrive = $false UpdateOneDrive = $true
UpdateLatestMSRT = $false UpdateLatestMSRT = $true
UpdateLatestMicrocode = $false # Added for UpdateLatestMicrocode UI control UpdateLatestMicrocode = $false
UpdatePreviewCU = $false UpdatePreviewCU = $false
# Applications Tab Defaults # Applications Tab Defaults
InstallApps = $false InstallApps = $false
@@ -437,19 +438,19 @@ function Get-GeneralDefaults {
InstallWingetApps = $false InstallWingetApps = $false
BringYourOwnApps = $false BringYourOwnApps = $false
# M365 Apps/Office Tab Defaults # M365 Apps/Office Tab Defaults
InstallOffice = $false InstallOffice = $true
OfficePath = $officePath OfficePath = $officePath
CopyOfficeConfigXML = $false CopyOfficeConfigXML = $false
OfficeConfigXMLFilePath = "" # Requires user input OfficeConfigXMLFilePath = ""
# Drivers Tab Defaults # Drivers Tab Defaults
DriversFolder = $driversPath DriversFolder = $driversPath
PEDriversFolder = $peDriversPath PEDriversFolder = $peDriversPath
DriversJsonPath = Join-Path -Path $driversPath -ChildPath "Drivers.json" DriversJsonPath = $driversJsonPath
DownloadDrivers = $false DownloadDrivers = $false
InstallDrivers = $false InstallDrivers = $false
CopyDrivers = $false CopyDrivers = $false
CopyPEDrivers = $false CopyPEDrivers = $false
UpdateADK = $true # Added for UpdateADK UI control UpdateADK = $true
} }
} }
@@ -3701,12 +3702,126 @@ function Invoke-ParallelProcessing {
# Return all collected final results from jobs # Return all collected final results from jobs
return $resultsCollection return $resultsCollection
} }
# --------------------------------------------------------------------------
# SECTION: UI Configuration
# --------------------------------------------------------------------------
function Get-UIConfig {
param(
[Parameter(Mandatory = $true)]
[psobject]$State
)
# Create hash to store configuration
$config = [ordered]@{
AllowExternalHardDiskMedia = $State.Controls.chkAllowExternalHardDiskMedia.IsChecked
AllowVHDXCaching = $State.Controls.chkAllowVHDXCaching.IsChecked
AppListPath = $State.Controls.txtAppListJsonPath.Text
AppsPath = $State.Controls.txtApplicationPath.Text
AppsScriptVariables = if ($State.Controls.chkDefineAppsScriptVariables.IsChecked) {
$vars = @{}
foreach ($item in $State.Data.appsScriptVariablesDataList) {
$vars[$item.Key] = $item.Value
}
if ($vars.Count -gt 0) { $vars } else { $null }
}
else { $null }
BuildUSBDrive = $State.Controls.chkBuildUSBDriveEnable.IsChecked
CleanupAppsISO = $State.Controls.chkCleanupAppsISO.IsChecked
CleanupCaptureISO = $State.Controls.chkCleanupCaptureISO.IsChecked
CleanupDeployISO = $State.Controls.chkCleanupDeployISO.IsChecked
CleanupDrivers = $State.Controls.chkCleanupDrivers.IsChecked
CompactOS = $State.Controls.chkCompactOS.IsChecked
CompressDownloadedDriversToWim = $State.Controls.chkCompressDriversToWIM.IsChecked
CopyAutopilot = $State.Controls.chkCopyAutopilot.IsChecked
CopyDrivers = $State.Controls.chkCopyDrivers.IsChecked
CopyOfficeConfigXML = $State.Controls.chkCopyOfficeConfigXML.IsChecked
CopyPEDrivers = $State.Controls.chkCopyPEDrivers.IsChecked
CopyPPKG = $State.Controls.chkCopyPPKG.IsChecked
CopyUnattend = $State.Controls.chkCopyUnattend.IsChecked
CreateCaptureMedia = $State.Controls.chkCreateCaptureMedia.IsChecked
CreateDeploymentMedia = $State.Controls.chkCreateDeploymentMedia.IsChecked
CustomFFUNameTemplate = $State.Controls.txtCustomFFUNameTemplate.Text
Disksize = [int64]$State.Controls.txtDiskSize.Text * 1GB
DownloadDrivers = $State.Controls.chkDownloadDrivers.IsChecked
DriversFolder = $State.Controls.txtDriversFolder.Text
DriversJsonPath = $State.Controls.txtDriversJsonPath.Text
FFUCaptureLocation = $State.Controls.txtFFUCaptureLocation.Text
FFUDevelopmentPath = $State.Controls.txtFFUDevPath.Text
FFUPrefix = $State.Controls.txtVMNamePrefix.Text
InstallApps = $State.Controls.chkInstallApps.IsChecked
InstallDrivers = $State.Controls.chkInstallDrivers.IsChecked
InstallOffice = $State.Controls.chkInstallOffice.IsChecked
InstallWingetApps = $State.Controls.chkInstallWingetApps.IsChecked
ISOPath = $State.Controls.txtISOPath.Text
LogicalSectorSizeBytes = [int]$State.Controls.cmbLogicalSectorSize.SelectedItem.Content
Make = $State.Controls.cmbMake.SelectedItem
MediaType = $State.Controls.cmbMediaType.SelectedItem
Memory = [int64]$State.Controls.txtMemory.Text * 1GB
Model = if ($State.Controls.chkDownloadDrivers.IsChecked) {
$selectedModels = $State.Controls.lstDriverModels.Items | Where-Object { $_.IsSelected }
if ($selectedModels.Count -ge 1) {
$selectedModels[0].Model
}
else {
$null
}
}
else {
$null
}
OfficeConfigXMLFile = $State.Controls.txtOfficeConfigXMLFilePath.Text
OfficePath = $State.Controls.txtOfficePath.Text
Optimize = $State.Controls.chkOptimize.IsChecked
OptionalFeatures = $State.Controls.txtOptionalFeatures.Text
OrchestrationPath = "$($State.Controls.txtApplicationPath.Text)\Orchestration"
PEDriversFolder = $State.Controls.txtPEDriversFolder.Text
Processors = [int]$State.Controls.txtProcessors.Text
ProductKey = $State.Controls.txtProductKey.Text
PromptExternalHardDiskMedia = $State.Controls.chkPromptExternalHardDiskMedia.IsChecked
RemoveApps = $State.Controls.chkRemoveApps.IsChecked
RemoveFFU = $State.Controls.chkRemoveFFU.IsChecked
RemoveUpdates = $State.Controls.chkRemoveUpdates.IsChecked
ShareName = $State.Controls.txtShareName.Text
UpdateADK = $State.Controls.chkUpdateADK.IsChecked
UpdateEdge = $State.Controls.chkUpdateEdge.IsChecked
UpdateLatestCU = $State.Controls.chkUpdateLatestCU.IsChecked
UpdateLatestDefender = $State.Controls.chkUpdateLatestDefender.IsChecked
UpdateLatestMicrocode = $State.Controls.chkUpdateLatestMicrocode.IsChecked
UpdateLatestMSRT = $State.Controls.chkUpdateLatestMSRT.IsChecked
UpdateLatestNet = $State.Controls.chkUpdateLatestNet.IsChecked
UpdateOneDrive = $State.Controls.chkUpdateOneDrive.IsChecked
UpdatePreviewCU = $State.Controls.chkUpdatePreviewCU.IsChecked
UserAppListPath = "$($State.Controls.txtApplicationPath.Text)\UserAppList.json"
USBDriveList = @{}
Username = $State.Controls.txtUsername.Text
VMHostIPAddress = $State.Controls.txtVMHostIPAddress.Text
VMLocation = $State.Controls.txtVMLocation.Text
VMSwitchName = if ($State.Controls.cmbVMSwitchName.SelectedItem -eq 'Other') {
$State.Controls.txtCustomVMSwitchName.Text
}
else {
$State.Controls.cmbVMSwitchName.SelectedItem
}
WindowsArch = $State.Controls.cmbWindowsArch.SelectedItem
WindowsLang = $State.Controls.cmbWindowsLang.SelectedItem
WindowsRelease = [int]$State.Controls.cmbWindowsRelease.SelectedItem.Value
WindowsSKU = $State.Controls.cmbWindowsSKU.SelectedItem
WindowsVersion = $State.Controls.cmbWindowsVersion.SelectedItem
}
$State.Controls.lstUSBDrives.Items | Where-Object { $_.IsSelected } | ForEach-Object {
$config.USBDriveList[$_.Model] = $_.SerialNumber
}
return $config
}
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# SECTION: Module Export # SECTION: Module Export
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Export only the functions intended for public use by the UI script # Export only the functions intended for public use by the UI script
Export-ModuleMember -Function Get-VMSwitchData, Export-ModuleMember -Function Get-UIConfig,
Get-VMSwitchData,
Get-WindowsSettingsDefaults, Get-WindowsSettingsDefaults,
Get-AvailableWindowsReleases, Get-AvailableWindowsReleases,
Get-AvailableWindowsVersions, Get-AvailableWindowsVersions,
@@ -0,0 +1,23 @@
- Work item name: Refactor `Get-UIConfig`
- Work item issue (e.g. what is the work item solving): The `Get-UIConfig` function currently accesses UI elements directly, making it tightly coupled to the main UI script and harder to maintain and test. This work item will refactor it to accept a central state object, improving modularity and aligning with the project's overall refactoring goals.
- Work Item plan:
- What the plan is: I will modify the `Get-UIConfig` function in `FFUUI.Core.psm1`. The function will be updated to accept a single `$State` object as a parameter. Inside the function, all references to UI controls will be changed to access them from the `$State.Controls` hashtable. This will decouple the function from the main script's global variables. I will then update the call to this function in `BuildFFUVM_UI.ps1` to pass the new `$script:uiState` object.
- Files modified:
- `FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1`
- `FFUDevelopment/BuildFFUVM_UI.ps1`
- Global/script variables and/or parameters created: None
- Functions created: None
- Any other important functionality: This change is a key part of the "Tame the script: Scope with a Central State Object" initiative. It will make the code cleaner, more maintainable, and easier to debug.
# Current Work Item
# Summary of Changes
- **Refactored `Get-UIConfig` function**:
- Moved the `Get-UIConfig` function from `BuildFFUVM_UI.ps1` to the `FFUUI.Core.psm1` module to improve code modularity and separation of concerns.
- Modified the function to accept a central `$State` object as a parameter, eliminating direct dependencies on global UI variables like `$window`.
- Updated all internal logic within `Get-UIConfig` to retrieve UI control values from the `$State.Controls` hashtable (e.g., `$State.Controls.chkCompactOS.IsChecked`).
- Updated the function calls in `BuildFFUVM_UI.ps1` (within the `btnRun` and `btnBuildConfig` click events) to pass the `$script:uiState` object to the refactored function.
- Exported `Get-UIConfig` from the `FFUUI.Core.psm1` module, making it accessible to the main UI script.
- **Files Modified**:
- `FFUDevelopment/BuildFFUVM_UI.ps1`: Removed the original function definition and updated the calls.
- `FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1`: Added the refactored function and exported it.