diff --git a/FFUDevelopment/BuildFFUVM_UI.ps1 b/FFUDevelopment/BuildFFUVM_UI.ps1 index 001e1f1..8866f86 100644 --- a/FFUDevelopment/BuildFFUVM_UI.ps1 +++ b/FFUDevelopment/BuildFFUVM_UI.ps1 @@ -202,159 +202,6 @@ if (Test-Path -Path $script:uiState.LogFilePath) { Remove-item -Path $script:uiState.LogFilePath -Force } -# Function to refresh the Windows Release ComboBox based on ISO path -function Update-WindowsReleaseCombo { - param( - [string]$isoPath, - [Parameter(Mandatory = $true)] - [psobject]$State - ) - - if (-not $State.Controls.cmbWindowsRelease) { return } - - $oldSelectedItemValue = $null - if ($null -ne $State.Controls.cmbWindowsRelease.SelectedItem) { - $oldSelectedItemValue = $State.Controls.cmbWindowsRelease.SelectedItem.Value - } - - # Get the appropriate list of releases from the helper module - $availableReleases = Get-AvailableWindowsReleases -IsoPath $isoPath -State $State - - # Update the ComboBox ItemsSource - $State.Controls.cmbWindowsRelease.ItemsSource = $availableReleases - $State.Controls.cmbWindowsRelease.DisplayMemberPath = 'Display' - $State.Controls.cmbWindowsRelease.SelectedValuePath = 'Value' - - # Try to re-select the previously selected item, or default - $itemToSelect = $availableReleases | Where-Object { $_.Value -eq $oldSelectedItemValue } | Select-Object -First 1 - if ($null -ne $itemToSelect) { - $State.Controls.cmbWindowsRelease.SelectedItem = $itemToSelect - } - elseif ($availableReleases.Count -gt 0) { - # Default to Windows 11 if available, otherwise the first item - $defaultItem = $availableReleases | Where-Object { $_.Value -eq 11 } | Select-Object -First 1 - if ($null -eq $defaultItem) { - $defaultItem = $availableReleases[0] - } - $State.Controls.cmbWindowsRelease.SelectedItem = $defaultItem - } - else { - # No items available (should not happen with current logic) - $State.Controls.cmbWindowsRelease.SelectedIndex = -1 - } -} - -# Function to refresh the Windows Version ComboBox based on selected release and ISO path -function Update-WindowsVersionCombo { - param( - [int]$selectedRelease, - [string]$isoPath, - [Parameter(Mandatory = $true)] - [psobject]$State - ) - - $combo = $State.Controls.cmbWindowsVersion - if (-not $combo) { return } - - # Get available versions and default from the helper module - $versionData = Get-AvailableWindowsVersions -SelectedRelease $selectedRelease -IsoPath $isoPath -State $State - - # Update the ComboBox ItemsSource and IsEnabled state - $combo.ItemsSource = $versionData.Versions - $combo.IsEnabled = $versionData.IsEnabled - - # Set the selected item - if ($null -ne $versionData.DefaultVersion -and $versionData.Versions -contains $versionData.DefaultVersion) { - $combo.SelectedItem = $versionData.DefaultVersion - } - elseif ($versionData.Versions.Count -gt 0) { - $combo.SelectedIndex = 0 - } - else { - $combo.SelectedIndex = -1 # No items available - } -} - -# Function to refresh the Windows SKU ComboBox based on selected release -function Update-WindowsSkuCombo { - param( - [Parameter(Mandatory = $true)] - [psobject]$State - ) - - $skuCombo = $State.Controls.cmbWindowsSKU - if (-not $skuCombo) { - WriteLog "Update-WindowsSkuCombo: SKU ComboBox not found." - return - } - - $releaseCombo = $script:uiState.Controls.cmbWindowsRelease - if (-not $releaseCombo -or $null -eq $releaseCombo.SelectedItem) { - WriteLog "Update-WindowsSkuCombo: Windows Release ComboBox not found or no item selected. Cannot update SKUs." - $skuCombo.ItemsSource = @() # Clear SKUs - $skuCombo.SelectedIndex = -1 - return - } - - $selectedReleaseItem = $releaseCombo.SelectedItem - $selectedReleaseValue = $selectedReleaseItem.Value - $selectedReleaseDisplayName = $selectedReleaseItem.Display - - $previousSelectedSku = $null - if ($null -ne $skuCombo.SelectedItem) { - $previousSelectedSku = $skuCombo.SelectedItem - } - - WriteLog "Update-WindowsSkuCombo: Updating SKUs for Release Value '$selectedReleaseValue' (Display: '$selectedReleaseDisplayName')." - # Call Get-AvailableSkusForRelease with both Value and DisplayName - $availableSkus = Get-AvailableSkusForRelease -SelectedReleaseValue $selectedReleaseValue -SelectedReleaseDisplayName $selectedReleaseDisplayName -State $State - - $skuCombo.ItemsSource = $availableSkus - WriteLog "Update-WindowsSkuCombo: Set ItemsSource with $($availableSkus.Count) SKUs." - - # Attempt to re-select the previous SKU, or "Pro", or the first available - if ($null -ne $previousSelectedSku -and $availableSkus -contains $previousSelectedSku) { - $skuCombo.SelectedItem = $previousSelectedSku - WriteLog "Update-WindowsSkuCombo: Re-selected previous SKU '$previousSelectedSku'." - } - elseif ($availableSkus -contains "Pro") { - $skuCombo.SelectedItem = "Pro" - WriteLog "Update-WindowsSkuCombo: Selected default SKU 'Pro'." - } - elseif ($availableSkus.Count -gt 0) { - $skuCombo.SelectedIndex = 0 - WriteLog "Update-WindowsSkuCombo: Selected first available SKU '$($skuCombo.SelectedItem)'." - } - else { - $skuCombo.SelectedIndex = -1 # No SKUs available - WriteLog "Update-WindowsSkuCombo: No SKUs available for Release '$selectedReleaseValue' (Display: '$selectedReleaseDisplayName')." - } -} - -# Combined function to refresh both Release and Version combos -function Refresh-WindowsSettingsCombos { - param( - [string]$isoPath, - [Parameter(Mandatory = $true)] - [psobject]$State - ) - - # Update Release combo first - Update-WindowsReleaseCombo -isoPath $isoPath -State $State - - # Get the newly selected release value - $selectedReleaseValue = 11 # Default to 11 if selection is null - if ($null -ne $State.Controls.cmbWindowsRelease.SelectedItem) { - $selectedReleaseValue = $State.Controls.cmbWindowsRelease.SelectedItem.Value - } - - # Update Version combo based on the selected release - Update-WindowsVersionCombo -selectedRelease $selectedReleaseValue -isoPath $isoPath -State $State - - # Update SKU combo based on the selected release (now derives values internally) - Update-WindowsSkuCombo -State $State -} - Add-Type -AssemblyName WindowsBase Add-Type -AssemblyName PresentationCore, PresentationFramework Add-Type -AssemblyName System.Windows.Forms @@ -370,69 +217,6 @@ $reader = New-Object System.IO.StringReader($xamlString) $xmlReader = [System.Xml.XmlReader]::Create($reader) $window = [Windows.Markup.XamlReader]::Load($xmlReader) -# Dynamic checkboxes for optional features in Windows Settings tab -function UpdateOptionalFeaturesString { - param( - [psobject]$State - ) - $checkedFeatures = @() - foreach ($entry in $State.Controls.featureCheckBoxes.GetEnumerator()) { - if ($entry.Value.IsChecked) { $checkedFeatures += $entry.Key } - } - $State.Controls.txtOptionalFeatures.Text = $checkedFeatures -join ";" -} -function BuildFeaturesGrid { - param ( - [Parameter(Mandatory)] - [System.Windows.FrameworkElement]$parent, - [Parameter(Mandatory)] - [array]$allowedFeatures # Pass the list of features explicitly - ) - $parent.Children.Clear() - $script:uiState.Controls.featureCheckBoxes.Clear() # Clear the tracking hashtable - - $sortedFeatures = $allowedFeatures | Sort-Object - $rows = 10 # Define number of rows for layout - $columns = [math]::Ceiling($sortedFeatures.Count / $rows) - - $featuresGrid = New-Object System.Windows.Controls.Grid - $featuresGrid.Margin = "0,5,0,5" - $featuresGrid.ShowGridLines = $false - - # Define grid rows - for ($r = 0; $r -lt $rows; $r++) { - $rowDef = New-Object System.Windows.Controls.RowDefinition - $rowDef.Height = [System.Windows.GridLength]::Auto - $featuresGrid.RowDefinitions.Add($rowDef) | Out-Null - } - # Define grid columns - for ($c = 0; $c -lt $columns; $c++) { - $colDef = New-Object System.Windows.Controls.ColumnDefinition - $colDef.Width = [System.Windows.GridLength]::Auto - $featuresGrid.ColumnDefinitions.Add($colDef) | Out-Null - } - - # Populate grid with checkboxes - for ($i = 0; $i -lt $sortedFeatures.Count; $i++) { - $featureName = $sortedFeatures[$i] - $colIndex = [int]([math]::Floor($i / $rows)) - $rowIndex = $i % $rows - - $chk = New-Object System.Windows.Controls.CheckBox - $chk.Content = $featureName - $chk.Margin = "5" - $chk.Add_Checked({ UpdateOptionalFeaturesString -State $script:uiState }) - $chk.Add_Unchecked({ UpdateOptionalFeaturesString -State $script:uiState }) - - $script:uiState.Controls.featureCheckBoxes[$featureName] = $chk # Track the checkbox - - [System.Windows.Controls.Grid]::SetRow($chk, $rowIndex) - [System.Windows.Controls.Grid]::SetColumn($chk, $colIndex) - $featuresGrid.Children.Add($chk) | Out-Null - } - $parent.Children.Add($featuresGrid) | Out-Null -} - # ----------------------------------------------------------------------------- # SECTION: Winget UI # ----------------------------------------------------------------------------- @@ -474,6 +258,7 @@ function Update-WingetVersionFields { $window.Add_Loaded({ # Pass the state object to all initialization functions $script:uiState.Window = $window + $window.Tag = $script:uiState # Store state in the window's Tag property Initialize-UIControls -State $script:uiState # Set ListViewItem style to stretch content horizontally so cell templates fill the cell @@ -1047,7 +832,7 @@ $window.Add_Loaded({ }) # Build dynamic multi-column checkboxes for optional features (Keep existing logic) - if ($script:uiState.Controls.featuresPanel) { BuildFeaturesGrid -parent $script:uiState.Controls.featuresPanel -allowedFeatures $script:uiState.Defaults.windowsSettingsDefaults.AllowedFeatures } + if ($script:uiState.Controls.featuresPanel) { BuildFeaturesGrid -parent $script:uiState.Controls.featuresPanel -allowedFeatures $script:uiState.Defaults.windowsSettingsDefaults.AllowedFeatures -State $script:uiState } # Updates/InstallApps interplay (Keep existing logic) $script:uiState.Flags.installAppsForcedByUpdates = $false diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.WindowsSettings.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.WindowsSettings.psm1 new file mode 100644 index 0000000..aee156a --- /dev/null +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.WindowsSettings.psm1 @@ -0,0 +1,571 @@ +# FFU UI Core Windows Settings Logic Module +# Contains UI helper functions, data retrieval, and core processing logic for the Windows Settings tab. + +# -------------------------------------------------------------------------- +# SECTION: Module Variables (Static Data) +# -------------------------------------------------------------------------- + +$script:allowedFeatures = @( + "AppServerClient", "Client-DeviceLockdown", "Client-EmbeddedBootExp", "Client-EmbeddedLogon", + "Client-EmbeddedShellLauncher", "Client-KeyboardFilter", "Client-ProjFS", "Client-UnifiedWriteFilter", + "Containers", "Containers-DisposableClientVM", "Containers-HNS", "Containers-SDN", "DataCenterBridging", + "DirectoryServices-ADAM-Client", "DirectPlay", "HostGuardian", "HypervisorPlatform", "IIS-ApplicationDevelopment", + "IIS-ApplicationInit", "IIS-ASP", "IIS-ASPNET45", "IIS-BasicAuthentication", "IIS-CertProvider", + "IIS-CGI", "IIS-ClientCertificateMappingAuthentication", "IIS-CommonHttpFeatures", "IIS-CustomLogging", + "IIS-DefaultDocument", "IIS-DirectoryBrowsing", "IIS-DigestAuthentication", "IIS-ESP", "IIS-FTPServer", + "IIS-FTPExtensibility", "IIS-FTPSvc", "IIS-HealthAndDiagnostics", "IIS-HostableWebCore", "IIS-HttpCompressionDynamic", + "IIS-HttpCompressionStatic", "IIS-HttpErrors", "IIS-HttpLogging", "IIS-HttpRedirect", "IIS-HttpTracing", + "IIS-IPSecurity", "IIS-IIS6ManagementCompatibility", "IIS-IISCertificateMappingAuthentication", + "IIS-ISAPIExtensions", "IIS-ISAPIFilter", "IIS-LoggingLibraries", "IIS-ManagementConsole", "IIS-ManagementService", + "IIS-ManagementScriptingTools", "IIS-Metabase", "IIS-NetFxExtensibility", "IIS-NetFxExtensibility45", + "IIS-ODBCLogging", "IIS-Performance", "IIS-RequestFiltering", "IIS-RequestMonitor", "IIS-Security", "IIS-ServerSideIncludes", + "IIS-StaticContent", "IIS-URLAuthorization", "IIS-WebDAV", "IIS-WebServer", "IIS-WebServerManagementTools", + "IIS-WebServerRole", "IIS-WebSockets", "LegacyComponents", "MediaPlayback", "Microsoft-Hyper-V", "Microsoft-Hyper-V-All", + "Microsoft-Hyper-V-Hypervisor", "Microsoft-Hyper-V-Management-Clients", "Microsoft-Hyper-V-Management-PowerShell", + "Microsoft-Hyper-V-Services", "Microsoft-Windows-Subsystem-Linux", "MSMQ-ADIntegration", "MSMQ-Container", "MSMQ-DCOMProxy", + "MSMQ-HTTP", "MSMQ-Multicast", "MSMQ-Server", "MSMQ-Triggers", "MultiPoint-Connector", "MultiPoint-Connector-Services", + "MultiPoint-Tools", "NetFx3", "NetFx4-AdvSrvs", "NetFx4Extended-ASPNET45", "NFS-Administration", "Printing-Foundation-Features", + "Printing-Foundation-InternetPrinting-Client", "Printing-Foundation-LPDPrintService", "Printing-Foundation-LPRPortMonitor", + "Printing-PrintToPDFServices-Features", "Printing-XPSServices-Features", "SearchEngine-Client-Package", + "ServicesForNFS-ClientOnly", "SimpleTCP", "SMB1Protocol", "SMB1Protocol-Client", "SMB1Protocol-Deprecation", + "SMB1Protocol-Server", "SmbDirect", "TFTP", "TelnetClient", "TIFFIFilter", "VirtualMachinePlatform", "WAS-ConfigurationAPI", + "WAS-NetFxEnvironment", "WAS-ProcessModel", "WAS-WindowsActivationService", "WCF-HTTP-Activation", "WCF-HTTP-Activation45", + "WCF-MSMQ-Activation45", "WCF-MSMQ-Activation", "WCF-NonHTTP-Activation", "WCF-Pipe-Activation45", "WCF-Services45", + "WCF-TCP-Activation45", "WCF-TCP-PortSharing45", "Windows-Defender-ApplicationGuard", + "Windows-Defender-Default-Definitions", "Windows-Identity-Foundation", "WindowsMediaPlayer", "WorkFolders-Client" +) + +$script:skuList = @( + 'Home', + 'Home N', + 'Home Single Language', + 'Education', + 'Education N', + 'Pro', + 'Pro N', + 'Pro Education', + 'Pro Education N', + 'Pro for Workstations', + 'Pro N for Workstations', + 'Enterprise', + 'Enterprise N', + 'Enterprise 2016 LTSB', + 'Enterprise N 2016 LTSB', + 'Enterprise LTSC', + 'Enterprise N LTSC', + 'IoT Enterprise LTSC', + 'IoT Enterprise N LTSC', + 'Standard', + 'Standard (Desktop Experience)', + 'Datacenter', + 'Datacenter (Desktop Experience)' +) + +$script:allowedLangs = @( + 'ar-sa', + 'bg-bg', + 'cs-cz', + 'da-dk', + 'de-de', + 'el-gr', + 'en-gb', + 'en-us', + 'es-es', + 'es-mx', + 'et-ee', + 'fi-fi', + 'fr-ca', + 'fr-fr', + 'he-il', + 'hr-hr', + 'hu-hu', + 'it-it', + 'ja-jp', + 'ko-kr', + 'lt-lt', + 'lv-lv', + 'nb-no', + 'nl-nl', + 'pl-pl', + 'pt-br', + 'pt-pt', + 'ro-ro', + 'ru-ru', + 'sk-sk', + 'sl-si', + 'sr-latn-rs', + 'sv-se', + 'th-th', + 'tr-tr', + 'uk-ua', + 'zh-cn', + 'zh-tw' +) + +$script:allWindowsReleases = @( + [PSCustomObject]@{ Display = "Windows 10"; Value = 10 }, + [PSCustomObject]@{ Display = "Windows 11"; Value = 11 }, + [PSCustomObject]@{ Display = "Windows Server 2016"; Value = 2016 }, + [PSCustomObject]@{ Display = "Windows Server 2019"; Value = 2019 }, + [PSCustomObject]@{ Display = "Windows Server 2022"; Value = 2022 }, + [PSCustomObject]@{ Display = "Windows Server 2025"; Value = 2025 }, + [PSCustomObject]@{ Display = "Windows 10 LTSB 2016"; Value = 2016 }, # Changed Value from 1607 + [PSCustomObject]@{ Display = "Windows 10 LTSC 2019"; Value = 2019 }, # Changed Value from 1809 + [PSCustomObject]@{ Display = "Windows 10 LTSC 2021"; Value = 2021 }, + [PSCustomObject]@{ Display = "Windows 10 LTSC 2024"; Value = 2024 } +) + +$script:mctWindowsReleases = @( + [PSCustomObject]@{ Display = "Windows 10"; Value = 10 }, + [PSCustomObject]@{ Display = "Windows 11"; Value = 11 } +) + +$script:windowsVersionMap = @{ + 10 = @("22H2") + 11 = @("22H2", "23H2", "24H2") + 2016 = @("1607") # Windows 10 LTSB 2016 & Server 2016 + 2019 = @("1809") # Windows 10 LTSC 2019 & Server 2019 + # Note: Server 2016 and LTSB 2016 now share the key 2016, mapping to version "1607" + # Note: Server 2019 and LTSC 2019 now share the key 2019, mapping to version "1809" + 2021 = @("21H2") # LTSC 2021 + 2022 = @("21H2") # Server 2022 + 2024 = @("24H2") # LTSC 2024 + 2025 = @("24H2") # Server 2025 +} + +# SKU Groups +$script:clientSKUs = @( + 'Home', + 'Home N', + 'Home Single Language', + 'Education', + 'Education N', + 'Pro', + 'Pro N', + 'Pro Education', + 'Pro Education N', + 'Pro for Workstations', + 'Pro N for Workstations', + 'Enterprise', + 'Enterprise N' +) + +$script:serverSKUs = @( + 'Standard', + 'Standard (Desktop Experience)', + 'Datacenter', + 'Datacenter (Desktop Experience)' +) + +$script:ltsc2016SKUs = @( + 'Enterprise 2016 LTSB', + 'Enterprise N 2016 LTSB' +) + +$script:ltscGenericSKUs = @( # For LTSC 2019, 2021, 2024 + 'Enterprise LTSC', + 'Enterprise N LTSC' +) + +$script:iotLtscSKUs = @( + 'IoT Enterprise LTSC', + 'IoT Enterprise N LTSC' + # Note: IoT SKUs are often specialized and might have different edition IDs. + # This list is a general representation. Actual ISOs might be needed for specific IoT LTSC editions. +) + +# Map Windows Release Values to their corresponding SKU lists +$script:windowsReleaseSkuMap = @{ + 10 = $script:clientSKUs # Windows 10 Client + 11 = $script:clientSKUs # Windows 11 Client + 2016 = $script:serverSKUs # Windows Server 2016 (LTSB 2016 handled by Get-AvailableSkusForRelease) + 2019 = $script:serverSKUs # Windows Server 2019 (LTSC 2019 handled by Get-AvailableSkusForRelease) + 2022 = $script:serverSKUs # Windows Server 2022 + 2025 = $script:serverSKUs # Windows Server 2025 + 2021 = $script:ltscGenericSKUs + $script:iotLtscSKUs # Windows 10 LTSC 2021 + 2024 = $script:ltscGenericSKUs + $script:iotLtscSKUs # Windows 10 LTSC 2024 + # Note: LTSC 2016 and LTSC 2019 SKUs are now conditionally returned by Get-AvailableSkusForRelease +} + +# -------------------------------------------------------------------------- +# SECTION: Functions +# -------------------------------------------------------------------------- + +# Function to return the default settings and static lists +function Get-WindowsSettingsDefaults { + [CmdletBinding()] + param() + + return [PSCustomObject]@{ + DefaultISOPath = "" + DefaultWindowsArch = "x64" + DefaultWindowsLang = "en-us" + DefaultWindowsSKU = "Pro" + DefaultMediaType = "Consumer" + DefaultOptionalFeatures = "" + DefaultProductKey = "" + AllowedFeatures = $script:allowedFeatures + AllowedLanguages = $script:allowedLangs + AllowedArchitectures = @('x86', 'x64', 'arm64') + AllowedMediaTypes = @('Consumer', 'Business') + # Static Data Lists/Maps + SkuList = $script:skuList + AllWindowsReleases = $script:allWindowsReleases + MctWindowsReleases = $script:mctWindowsReleases + WindowsVersionMap = $script:windowsVersionMap + ClientSKUs = $script:clientSKUs + ServerSKUs = $script:serverSKUs + Ltsc2016SKUs = $script:ltsc2016SKUs + LtscGenericSKUs = $script:ltscGenericSKUs + IotLtscSKUs = $script:iotLtscSKUs + WindowsReleaseSkuMap = $script:windowsReleaseSkuMap + } +} + +# Function to get the appropriate list of Windows Releases based on ISO path +function Get-AvailableWindowsReleases { + [CmdletBinding()] + param( + [string]$IsoPath, + [Parameter(Mandatory = $true)] + [psobject]$State + ) + + if ([string]::IsNullOrEmpty($IsoPath)) { + return $State.Defaults.WindowsSettingsDefaults.MctWindowsReleases + } + else { + return $State.Defaults.WindowsSettingsDefaults.AllWindowsReleases + } +} + +# Function to get available Windows Versions for a given release and ISO path +function Get-AvailableWindowsVersions { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [int]$SelectedRelease, + + [string]$IsoPath, + [Parameter(Mandatory = $true)] + [psobject]$State + ) + + $result = [PSCustomObject]@{ + Versions = @() + DefaultVersion = $null + IsEnabled = $false + } + + if (-not $State.Defaults.WindowsSettingsDefaults.WindowsVersionMap.ContainsKey($SelectedRelease)) { + return $result + } + + $validVersions = $State.Defaults.WindowsSettingsDefaults.WindowsVersionMap[$SelectedRelease] + + if ([string]::IsNullOrEmpty($IsoPath)) { + # Logic for when no ISO is specified (MCT scenario) + switch ($SelectedRelease) { + 10 { $result.DefaultVersion = "22H2" } + 11 { $result.DefaultVersion = "24H2" } + # Server versions typically require an ISO, but handle just in case + 2016 { $result.DefaultVersion = "1607" } + 2019 { $result.DefaultVersion = "1809" } + 2022 { $result.DefaultVersion = "21H2" } + 2025 { $result.DefaultVersion = "24H2" } + default { $result.DefaultVersion = $validVersions[0] } + } + $result.Versions = @($result.DefaultVersion) # Only the default is available/relevant + $result.IsEnabled = $false # Combo should be disabled + } + else { + # Logic for when an ISO is specified + $result.Versions = $validVersions + # Set default selection logic (e.g., latest for Win11) + if ($SelectedRelease -eq 11 -and $validVersions -contains "24H2") { + $result.DefaultVersion = "24H2" + } + elseif ($validVersions.Count -gt 0) { + $result.DefaultVersion = $validVersions[0] + } + $result.IsEnabled = $true + } + + return $result +} + +# Function to get available SKUs for a given Windows Release value and display name +function Get-AvailableSkusForRelease { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [int]$SelectedReleaseValue, + + [Parameter(Mandatory)] + [string]$SelectedReleaseDisplayName, + [Parameter(Mandatory = $true)] + [psobject]$State + ) + + WriteLog "Get-AvailableSkusForRelease: Getting SKUs for Release Value '$SelectedReleaseValue', Display Name '$SelectedReleaseDisplayName'." + + # Handle LTSC 2016 specifically + if ($SelectedReleaseValue -eq 2016 -and $SelectedReleaseDisplayName -like '*LTSB*') { + WriteLog "Get-AvailableSkusForRelease: Matched LTSB 2016. Returning LTSC 2016 SKUs." + return $State.Defaults.WindowsSettingsDefaults.Ltsc2016SKUs + } + # Handle LTSC 2019 specifically + # Ensure "Server" is not in the display name to avoid matching "Windows Server 2019" + elseif ($SelectedReleaseValue -eq 2019 -and $SelectedReleaseDisplayName -like '*LTSC*' -and $SelectedReleaseDisplayName -notlike '*Server*') { + WriteLog "Get-AvailableSkusForRelease: Matched LTSC 2019. Returning generic LTSC SKUs (including IoT)." + # Assuming LTSC 2019 uses the generic LTSC SKUs + IoT LTSC SKUs + return ($State.Defaults.WindowsSettingsDefaults.LtscGenericSKUs + $State.Defaults.WindowsSettingsDefaults.IotLtscSKUs | Select-Object -Unique) + } + # For all other cases, use the main SKU map + elseif ($State.Defaults.WindowsSettingsDefaults.WindowsReleaseSkuMap.ContainsKey($SelectedReleaseValue)) { + $availableSkus = $State.Defaults.WindowsSettingsDefaults.WindowsReleaseSkuMap[$SelectedReleaseValue] + WriteLog "Get-AvailableSkusForRelease: Found $($availableSkus.Count) SKUs for Release '$SelectedReleaseValue' using standard map." + return $availableSkus + } + else { + WriteLog "Get-AvailableSkusForRelease: Warning - Release Value '$SelectedReleaseValue' not found in SKU map. Returning default client SKUs." + # Fallback to a default list (e.g., client SKUs) or an empty list + return $State.Defaults.WindowsSettingsDefaults.ClientSKUs + } +} + +# Function to refresh the Windows Release ComboBox based on ISO path +function Update-WindowsReleaseCombo { + param( + [string]$isoPath, + [Parameter(Mandatory = $true)] + [psobject]$State + ) + + if (-not $State.Controls.cmbWindowsRelease) { return } + + $oldSelectedItemValue = $null + if ($null -ne $State.Controls.cmbWindowsRelease.SelectedItem) { + $oldSelectedItemValue = $State.Controls.cmbWindowsRelease.SelectedItem.Value + } + + # Get the appropriate list of releases from the helper module + $availableReleases = Get-AvailableWindowsReleases -IsoPath $isoPath -State $State + + # Update the ComboBox ItemsSource + $State.Controls.cmbWindowsRelease.ItemsSource = $availableReleases + $State.Controls.cmbWindowsRelease.DisplayMemberPath = 'Display' + $State.Controls.cmbWindowsRelease.SelectedValuePath = 'Value' + + # Try to re-select the previously selected item, or default + $itemToSelect = $availableReleases | Where-Object { $_.Value -eq $oldSelectedItemValue } | Select-Object -First 1 + if ($null -ne $itemToSelect) { + $State.Controls.cmbWindowsRelease.SelectedItem = $itemToSelect + } + elseif ($availableReleases.Count -gt 0) { + # Default to Windows 11 if available, otherwise the first item + $defaultItem = $availableReleases | Where-Object { $_.Value -eq 11 } | Select-Object -First 1 + if ($null -eq $defaultItem) { + $defaultItem = $availableReleases[0] + } + $State.Controls.cmbWindowsRelease.SelectedItem = $defaultItem + } + else { + # No items available (should not happen with current logic) + $State.Controls.cmbWindowsRelease.SelectedIndex = -1 + } +} + +# Function to refresh the Windows Version ComboBox based on selected release and ISO path +function Update-WindowsVersionCombo { + param( + [int]$selectedRelease, + [string]$isoPath, + [Parameter(Mandatory = $true)] + [psobject]$State + ) + + $combo = $State.Controls.cmbWindowsVersion + if (-not $combo) { return } + + # Get available versions and default from the helper module + $versionData = Get-AvailableWindowsVersions -SelectedRelease $selectedRelease -IsoPath $isoPath -State $State + + # Update the ComboBox ItemsSource and IsEnabled state + $combo.ItemsSource = $versionData.Versions + $combo.IsEnabled = $versionData.IsEnabled + + # Set the selected item + if ($null -ne $versionData.DefaultVersion -and $versionData.Versions -contains $versionData.DefaultVersion) { + $combo.SelectedItem = $versionData.DefaultVersion + } + elseif ($versionData.Versions.Count -gt 0) { + $combo.SelectedIndex = 0 + } + else { + $combo.SelectedIndex = -1 # No items available + } +} + +# Function to refresh the Windows SKU ComboBox based on selected release +function Update-WindowsSkuCombo { + param( + [Parameter(Mandatory = $true)] + [psobject]$State + ) + + $skuCombo = $State.Controls.cmbWindowsSKU + if (-not $skuCombo) { + WriteLog "Update-WindowsSkuCombo: SKU ComboBox not found." + return + } + + $releaseCombo = $State.Controls.cmbWindowsRelease + if (-not $releaseCombo -or $null -eq $releaseCombo.SelectedItem) { + WriteLog "Update-WindowsSkuCombo: Windows Release ComboBox not found or no item selected. Cannot update SKUs." + $skuCombo.ItemsSource = @() # Clear SKUs + $skuCombo.SelectedIndex = -1 + return + } + + $selectedReleaseItem = $releaseCombo.SelectedItem + $selectedReleaseValue = $selectedReleaseItem.Value + $selectedReleaseDisplayName = $selectedReleaseItem.Display + + $previousSelectedSku = $null + if ($null -ne $skuCombo.SelectedItem) { + $previousSelectedSku = $skuCombo.SelectedItem + } + + WriteLog "Update-WindowsSkuCombo: Updating SKUs for Release Value '$selectedReleaseValue' (Display: '$selectedReleaseDisplayName')." + # Call Get-AvailableSkusForRelease with both Value and DisplayName + $availableSkus = Get-AvailableSkusForRelease -SelectedReleaseValue $selectedReleaseValue -SelectedReleaseDisplayName $selectedReleaseDisplayName -State $State + + $skuCombo.ItemsSource = $availableSkus + WriteLog "Update-WindowsSkuCombo: Set ItemsSource with $($availableSkus.Count) SKUs." + + # Attempt to re-select the previous SKU, or "Pro", or the first available + if ($null -ne $previousSelectedSku -and $availableSkus -contains $previousSelectedSku) { + $skuCombo.SelectedItem = $previousSelectedSku + WriteLog "Update-WindowsSkuCombo: Re-selected previous SKU '$previousSelectedSku'." + } + elseif ($availableSkus -contains "Pro") { + $skuCombo.SelectedItem = "Pro" + WriteLog "Update-WindowsSkuCombo: Selected default SKU 'Pro'." + } + elseif ($availableSkus.Count -gt 0) { + $skuCombo.SelectedIndex = 0 + WriteLog "Update-WindowsSkuCombo: Selected first available SKU '$($skuCombo.SelectedItem)'." + } + else { + $skuCombo.SelectedIndex = -1 # No SKUs available + WriteLog "Update-WindowsSkuCombo: No SKUs available for Release '$selectedReleaseValue' (Display: '$selectedReleaseDisplayName')." + } +} + +# Combined function to refresh both Release and Version combos +function Refresh-WindowsSettingsCombos { + param( + [string]$isoPath, + [Parameter(Mandatory = $true)] + [psobject]$State + ) + + # Update Release combo first + Update-WindowsReleaseCombo -isoPath $isoPath -State $State + + # Get the newly selected release value + $selectedReleaseValue = 11 # Default to 11 if selection is null + if ($null -ne $State.Controls.cmbWindowsRelease.SelectedItem) { + $selectedReleaseValue = $State.Controls.cmbWindowsRelease.SelectedItem.Value + } + + # Update Version combo based on the selected release + Update-WindowsVersionCombo -selectedRelease $selectedReleaseValue -isoPath $isoPath -State $State + + # Update SKU combo based on the selected release (now derives values internally) + Update-WindowsSkuCombo -State $State +} + +# Dynamic checkboxes for optional features in Windows Settings tab +function UpdateOptionalFeaturesString { + param( + [psobject]$State + ) + $checkedFeatures = @() + foreach ($entry in $State.Controls.featureCheckBoxes.GetEnumerator()) { + if ($entry.Value.IsChecked) { $checkedFeatures += $entry.Key } + } + $State.Controls.txtOptionalFeatures.Text = $checkedFeatures -join ";" +} +function BuildFeaturesGrid { + param ( + [Parameter(Mandatory)] + [System.Windows.FrameworkElement]$parent, + [Parameter(Mandatory)] + [array]$allowedFeatures, # Pass the list of features explicitly + [Parameter(Mandatory = $true)] + [psobject]$State + ) + $parent.Children.Clear() + $State.Controls.featureCheckBoxes.Clear() # Clear the tracking hashtable + + $sortedFeatures = $allowedFeatures | Sort-Object + $rows = 10 # Define number of rows for layout + $columns = [math]::Ceiling($sortedFeatures.Count / $rows) + + $featuresGrid = New-Object System.Windows.Controls.Grid + $featuresGrid.Margin = "0,5,0,5" + $featuresGrid.ShowGridLines = $false + + # Define grid rows + for ($r = 0; $r -lt $rows; $r++) { + $rowDef = New-Object System.Windows.Controls.RowDefinition + $rowDef.Height = [System.Windows.GridLength]::Auto + $featuresGrid.RowDefinitions.Add($rowDef) | Out-Null + } + # Define grid columns + for ($c = 0; $c -lt $columns; $c++) { + $colDef = New-Object System.Windows.Controls.ColumnDefinition + $colDef.Width = [System.Windows.GridLength]::Auto + $featuresGrid.ColumnDefinitions.Add($colDef) | Out-Null + } + + # Populate grid with checkboxes + for ($i = 0; $i -lt $sortedFeatures.Count; $i++) { + $featureName = $sortedFeatures[$i] + $colIndex = [int]([math]::Floor($i / $rows)) + $rowIndex = $i % $rows + + $chk = New-Object System.Windows.Controls.CheckBox + $chk.Content = $featureName + $chk.Margin = "5" + $chk.Add_Checked({ + param($sender, $e) + $window = [System.Windows.Window]::GetWindow($sender) + if ($null -ne $window) { + UpdateOptionalFeaturesString -State $window.Tag + } + }) + $chk.Add_Unchecked({ + param($sender, $e) + $window = [System.Windows.Window]::GetWindow($sender) + if ($null -ne $window) { + UpdateOptionalFeaturesString -State $window.Tag + } + }) + + $State.Controls.featureCheckBoxes[$featureName] = $chk # Track the checkbox + + [System.Windows.Controls.Grid]::SetRow($chk, $rowIndex) + [System.Windows.Controls.Grid]::SetColumn($chk, $colIndex) + $featuresGrid.Children.Add($chk) | Out-Null + } + $parent.Children.Add($featuresGrid) | Out-Null +} + +# -------------------------------------------------------------------------- +# SECTION: Module Export +# -------------------------------------------------------------------------- + +Export-ModuleMember -Function Get-WindowsSettingsDefaults, Get-AvailableWindowsReleases, Get-AvailableWindowsVersions, Get-AvailableSkusForRelease, Update-WindowsReleaseCombo, Update-WindowsVersionCombo, Update-WindowsSkuCombo, Refresh-WindowsSettingsCombos, UpdateOptionalFeaturesString, BuildFeaturesGrid \ No newline at end of file diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psd1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psd1 index 3f6f1b9..86f1151 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psd1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psd1 @@ -73,6 +73,7 @@ NestedModules = @('FFUUI.Core.Shared.psm1', 'FFUUI.Core.Drivers.HP.psm1', 'FFUUI.Core.Drivers.Lenovo.psm1', 'FFUUI.Core.Drivers.Microsoft.psm1', + 'FFUUI.Core.WindowsSettings.psm1', 'FFUUI.Core.Winget.psm1') # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 index 20d0d3b..2344940 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 @@ -24,187 +24,6 @@ $script:Headers = @{ } $script:UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0' -$script:allowedFeatures = @( - "AppServerClient", "Client-DeviceLockdown", "Client-EmbeddedBootExp", "Client-EmbeddedLogon", - "Client-EmbeddedShellLauncher", "Client-KeyboardFilter", "Client-ProjFS", "Client-UnifiedWriteFilter", - "Containers", "Containers-DisposableClientVM", "Containers-HNS", "Containers-SDN", "DataCenterBridging", - "DirectoryServices-ADAM-Client", "DirectPlay", "HostGuardian", "HypervisorPlatform", "IIS-ApplicationDevelopment", - "IIS-ApplicationInit", "IIS-ASP", "IIS-ASPNET45", "IIS-BasicAuthentication", "IIS-CertProvider", - "IIS-CGI", "IIS-ClientCertificateMappingAuthentication", "IIS-CommonHttpFeatures", "IIS-CustomLogging", - "IIS-DefaultDocument", "IIS-DirectoryBrowsing", "IIS-DigestAuthentication", "IIS-ESP", "IIS-FTPServer", - "IIS-FTPExtensibility", "IIS-FTPSvc", "IIS-HealthAndDiagnostics", "IIS-HostableWebCore", "IIS-HttpCompressionDynamic", - "IIS-HttpCompressionStatic", "IIS-HttpErrors", "IIS-HttpLogging", "IIS-HttpRedirect", "IIS-HttpTracing", - "IIS-IPSecurity", "IIS-IIS6ManagementCompatibility", "IIS-IISCertificateMappingAuthentication", - "IIS-ISAPIExtensions", "IIS-ISAPIFilter", "IIS-LoggingLibraries", "IIS-ManagementConsole", "IIS-ManagementService", - "IIS-ManagementScriptingTools", "IIS-Metabase", "IIS-NetFxExtensibility", "IIS-NetFxExtensibility45", - "IIS-ODBCLogging", "IIS-Performance", "IIS-RequestFiltering", "IIS-RequestMonitor", "IIS-Security", "IIS-ServerSideIncludes", - "IIS-StaticContent", "IIS-URLAuthorization", "IIS-WebDAV", "IIS-WebServer", "IIS-WebServerManagementTools", - "IIS-WebServerRole", "IIS-WebSockets", "LegacyComponents", "MediaPlayback", "Microsoft-Hyper-V", "Microsoft-Hyper-V-All", - "Microsoft-Hyper-V-Hypervisor", "Microsoft-Hyper-V-Management-Clients", "Microsoft-Hyper-V-Management-PowerShell", - "Microsoft-Hyper-V-Services", "Microsoft-Windows-Subsystem-Linux", "MSMQ-ADIntegration", "MSMQ-Container", "MSMQ-DCOMProxy", - "MSMQ-HTTP", "MSMQ-Multicast", "MSMQ-Server", "MSMQ-Triggers", "MultiPoint-Connector", "MultiPoint-Connector-Services", - "MultiPoint-Tools", "NetFx3", "NetFx4-AdvSrvs", "NetFx4Extended-ASPNET45", "NFS-Administration", "Printing-Foundation-Features", - "Printing-Foundation-InternetPrinting-Client", "Printing-Foundation-LPDPrintService", "Printing-Foundation-LPRPortMonitor", - "Printing-PrintToPDFServices-Features", "Printing-XPSServices-Features", "SearchEngine-Client-Package", - "ServicesForNFS-ClientOnly", "SimpleTCP", "SMB1Protocol", "SMB1Protocol-Client", "SMB1Protocol-Deprecation", - "SMB1Protocol-Server", "SmbDirect", "TFTP", "TelnetClient", "TIFFIFilter", "VirtualMachinePlatform", "WAS-ConfigurationAPI", - "WAS-NetFxEnvironment", "WAS-ProcessModel", "WAS-WindowsActivationService", "WCF-HTTP-Activation", "WCF-HTTP-Activation45", - "WCF-MSMQ-Activation45", "WCF-MSMQ-Activation", "WCF-NonHTTP-Activation", "WCF-Pipe-Activation45", "WCF-Services45", - "WCF-TCP-Activation45", "WCF-TCP-PortSharing45", "Windows-Defender-ApplicationGuard", - "Windows-Defender-Default-Definitions", "Windows-Identity-Foundation", "WindowsMediaPlayer", "WorkFolders-Client" -) - -$script:skuList = @( - 'Home', - 'Home N', - 'Home Single Language', - 'Education', - 'Education N', - 'Pro', - 'Pro N', - 'Pro Education', - 'Pro Education N', - 'Pro for Workstations', - 'Pro N for Workstations', - 'Enterprise', - 'Enterprise N', - 'Enterprise 2016 LTSB', - 'Enterprise N 2016 LTSB', - 'Enterprise LTSC', - 'Enterprise N LTSC', - 'IoT Enterprise LTSC', - 'IoT Enterprise N LTSC', - 'Standard', - 'Standard (Desktop Experience)', - 'Datacenter', - 'Datacenter (Desktop Experience)' -) - -$script:allowedLangs = @( - 'ar-sa', - 'bg-bg', - 'cs-cz', - 'da-dk', - 'de-de', - 'el-gr', - 'en-gb', - 'en-us', - 'es-es', - 'es-mx', - 'et-ee', - 'fi-fi', - 'fr-ca', - 'fr-fr', - 'he-il', - 'hr-hr', - 'hu-hu', - 'it-it', - 'ja-jp', - 'ko-kr', - 'lt-lt', - 'lv-lv', - 'nb-no', - 'nl-nl', - 'pl-pl', - 'pt-br', - 'pt-pt', - 'ro-ro', - 'ru-ru', - 'sk-sk', - 'sl-si', - 'sr-latn-rs', - 'sv-se', - 'th-th', - 'tr-tr', - 'uk-ua', - 'zh-cn', - 'zh-tw' -) - -$script:allWindowsReleases = @( - [PSCustomObject]@{ Display = "Windows 10"; Value = 10 }, - [PSCustomObject]@{ Display = "Windows 11"; Value = 11 }, - [PSCustomObject]@{ Display = "Windows Server 2016"; Value = 2016 }, - [PSCustomObject]@{ Display = "Windows Server 2019"; Value = 2019 }, - [PSCustomObject]@{ Display = "Windows Server 2022"; Value = 2022 }, - [PSCustomObject]@{ Display = "Windows Server 2025"; Value = 2025 }, - [PSCustomObject]@{ Display = "Windows 10 LTSB 2016"; Value = 2016 }, # Changed Value from 1607 - [PSCustomObject]@{ Display = "Windows 10 LTSC 2019"; Value = 2019 }, # Changed Value from 1809 - [PSCustomObject]@{ Display = "Windows 10 LTSC 2021"; Value = 2021 }, - [PSCustomObject]@{ Display = "Windows 10 LTSC 2024"; Value = 2024 } -) - -$script:mctWindowsReleases = @( - [PSCustomObject]@{ Display = "Windows 10"; Value = 10 }, - [PSCustomObject]@{ Display = "Windows 11"; Value = 11 } -) - -$script:windowsVersionMap = @{ - 10 = @("22H2") - 11 = @("22H2", "23H2", "24H2") - 2016 = @("1607") # Windows 10 LTSB 2016 & Server 2016 - 2019 = @("1809") # Windows 10 LTSC 2019 & Server 2019 - # Note: Server 2016 and LTSB 2016 now share the key 2016, mapping to version "1607" - # Note: Server 2019 and LTSC 2019 now share the key 2019, mapping to version "1809" - 2021 = @("21H2") # LTSC 2021 - 2022 = @("21H2") # Server 2022 - 2024 = @("24H2") # LTSC 2024 - 2025 = @("24H2") # Server 2025 -} - -# SKU Groups -$script:clientSKUs = @( - 'Home', - 'Home N', - 'Home Single Language', - 'Education', - 'Education N', - 'Pro', - 'Pro N', - 'Pro Education', - 'Pro Education N', - 'Pro for Workstations', - 'Pro N for Workstations', - 'Enterprise', - 'Enterprise N' -) - -$script:serverSKUs = @( - 'Standard', - 'Standard (Desktop Experience)', - 'Datacenter', - 'Datacenter (Desktop Experience)' -) - -$script:ltsc2016SKUs = @( - 'Enterprise 2016 LTSB', - 'Enterprise N 2016 LTSB' -) - -$script:ltscGenericSKUs = @( # For LTSC 2019, 2021, 2024 - 'Enterprise LTSC', - 'Enterprise N LTSC' -) - -$script:iotLtscSKUs = @( - 'IoT Enterprise LTSC', - 'IoT Enterprise N LTSC' - # Note: IoT SKUs are often specialized and might have different edition IDs. - # This list is a general representation. Actual ISOs might be needed for specific IoT LTSC editions. -) - -# Map Windows Release Values to their corresponding SKU lists -$script:windowsReleaseSkuMap = @{ - 10 = $script:clientSKUs # Windows 10 Client - 11 = $script:clientSKUs # Windows 11 Client - 2016 = $script:serverSKUs # Windows Server 2016 (LTSB 2016 handled by Get-AvailableSkusForRelease) - 2019 = $script:serverSKUs # Windows Server 2019 (LTSC 2019 handled by Get-AvailableSkusForRelease) - 2022 = $script:serverSKUs # Windows Server 2022 - 2025 = $script:serverSKUs # Windows Server 2025 - 2021 = $script:ltscGenericSKUs + $script:iotLtscSKUs # Windows 10 LTSC 2021 - 2024 = $script:ltscGenericSKUs + $script:iotLtscSKUs # Windows 10 LTSC 2024 - # Note: LTSC 2016 and LTSC 2019 SKUs are now conditionally returned by Get-AvailableSkusForRelease -} function Get-CoreStaticVariables { [CmdletBinding()] param() @@ -271,138 +90,6 @@ function Get-VMSwitchData { } } -# Function to return the default settings and static lists (Moved from UI_Helpers) -function Get-WindowsSettingsDefaults { - [CmdletBinding()] - param() - - return [PSCustomObject]@{ - DefaultISOPath = "" - DefaultWindowsArch = "x64" - DefaultWindowsLang = "en-us" - DefaultWindowsSKU = "Pro" - DefaultMediaType = "Consumer" - DefaultOptionalFeatures = "" - DefaultProductKey = "" - AllowedFeatures = $script:allowedFeatures - AllowedLanguages = $script:allowedLangs - AllowedArchitectures = @('x86', 'x64', 'arm64') - AllowedMediaTypes = @('Consumer', 'Business') - } -} - -# Function to get the appropriate list of Windows Releases based on ISO path (Moved from UI_Helpers) -function Get-AvailableWindowsReleases { - [CmdletBinding()] - param( - [string]$IsoPath, - [Parameter(Mandatory = $true)] - [psobject]$State - ) - - if ([string]::IsNullOrEmpty($IsoPath)) { - return $State.Defaults.GeneralDefaults.MctWindowsReleases - } - else { - return $State.Defaults.GeneralDefaults.AllWindowsReleases - } -} - -# Function to get available Windows Versions for a given release and ISO path (Moved from UI_Helpers) -function Get-AvailableWindowsVersions { - [CmdletBinding()] - param( - [Parameter(Mandatory)] - [int]$SelectedRelease, - - [string]$IsoPath, - [Parameter(Mandatory = $true)] - [psobject]$State - ) - - $result = [PSCustomObject]@{ - Versions = @() - DefaultVersion = $null - IsEnabled = $false - } - - if (-not $State.Defaults.GeneralDefaults.WindowsVersionMap.ContainsKey($SelectedRelease)) { - return $result - } - - $validVersions = $State.Defaults.GeneralDefaults.WindowsVersionMap[$SelectedRelease] - - if ([string]::IsNullOrEmpty($IsoPath)) { - # Logic for when no ISO is specified (MCT scenario) - switch ($SelectedRelease) { - 10 { $result.DefaultVersion = "22H2" } - 11 { $result.DefaultVersion = "24H2" } - # Server versions typically require an ISO, but handle just in case - 2016 { $result.DefaultVersion = "1607" } - 2019 { $result.DefaultVersion = "1809" } - 2022 { $result.DefaultVersion = "21H2" } - 2025 { $result.DefaultVersion = "24H2" } - default { $result.DefaultVersion = $validVersions[0] } - } - $result.Versions = @($result.DefaultVersion) # Only the default is available/relevant - $result.IsEnabled = $false # Combo should be disabled - } - else { - # Logic for when an ISO is specified - $result.Versions = $validVersions - # Set default selection logic (e.g., latest for Win11) - if ($SelectedRelease -eq 11 -and $validVersions -contains "24H2") { - $result.DefaultVersion = "24H2" - } - elseif ($validVersions.Count -gt 0) { - $result.DefaultVersion = $validVersions[0] - } - $result.IsEnabled = $true - } - - return $result -} - -# Function to get available SKUs for a given Windows Release value and display name -function Get-AvailableSkusForRelease { - [CmdletBinding()] - param( - [Parameter(Mandatory)] - [int]$SelectedReleaseValue, - - [Parameter(Mandatory)] - [string]$SelectedReleaseDisplayName, - [Parameter(Mandatory = $true)] - [psobject]$State - ) - - WriteLog "Get-AvailableSkusForRelease: Getting SKUs for Release Value '$SelectedReleaseValue', Display Name '$SelectedReleaseDisplayName'." - - # Handle LTSC 2016 specifically - if ($SelectedReleaseValue -eq 2016 -and $SelectedReleaseDisplayName -like '*LTSB*') { - WriteLog "Get-AvailableSkusForRelease: Matched LTSB 2016. Returning LTSC 2016 SKUs." - return $State.Defaults.GeneralDefaults.Ltsc2016SKUs - } - # Handle LTSC 2019 specifically - # Ensure "Server" is not in the display name to avoid matching "Windows Server 2019" - elseif ($SelectedReleaseValue -eq 2019 -and $SelectedReleaseDisplayName -like '*LTSC*' -and $SelectedReleaseDisplayName -notlike '*Server*') { - WriteLog "Get-AvailableSkusForRelease: Matched LTSC 2019. Returning generic LTSC SKUs (including IoT)." - # Assuming LTSC 2019 uses the generic LTSC SKUs + IoT LTSC SKUs - return ($State.Defaults.GeneralDefaults.LtscGenericSKUs + $State.Defaults.GeneralDefaults.IotLtscSKUs | Select-Object -Unique) - } - # For all other cases, use the main SKU map - elseif ($State.Defaults.GeneralDefaults.WindowsReleaseSkuMap.ContainsKey($SelectedReleaseValue)) { - $availableSkus = $State.Defaults.GeneralDefaults.WindowsReleaseSkuMap[$SelectedReleaseValue] - WriteLog "Get-AvailableSkusForRelease: Found $($availableSkus.Count) SKUs for Release '$SelectedReleaseValue' using standard map." - return $availableSkus - } - else { - WriteLog "Get-AvailableSkusForRelease: Warning - Release Value '$SelectedReleaseValue' not found in SKU map. Returning default client SKUs." - # Fallback to a default list (e.g., client SKUs) or an empty list - return $State.Defaults.GeneralDefaults.ClientSKUs - } -} - # Function to return general default settings for various UI elements function Get-GeneralDefaults { [CmdletBinding()] @@ -482,20 +169,7 @@ function Get-GeneralDefaults { InstallDrivers = $false CopyDrivers = $false CopyPEDrivers = $false - UpdateADK = $true - # Static Data Lists/Maps - AllowedFeatures = $script:allowedFeatures - SkuList = $script:skuList - AllowedLanguages = $script:allowedLangs - AllWindowsReleases = $script:allWindowsReleases - MctWindowsReleases = $script:mctWindowsReleases - WindowsVersionMap = $script:windowsVersionMap - ClientSKUs = $script:clientSKUs - ServerSKUs = $script:serverSKUs - Ltsc2016SKUs = $script:ltsc2016SKUs - LtscGenericSKUs = $script:ltscGenericSKUs - IotLtscSKUs = $script:iotLtscSKUs - WindowsReleaseSkuMap = $script:windowsReleaseSkuMap + UpdateADK = $true } }