mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
869 lines
44 KiB
PowerShell
869 lines
44 KiB
PowerShell
[CmdletBinding()]
|
|
[System.STAThread()]
|
|
param()
|
|
|
|
# --------------------------------------------------------------------------
|
|
# SECTION 1: Variables & Constants
|
|
# --------------------------------------------------------------------------
|
|
$FFUDevelopmentPath = $PSScriptRoot
|
|
$AppsPath = Join-Path $FFUDevelopmentPath "Apps"
|
|
$OfficePath = Join-Path $AppsPath "Office"
|
|
|
|
# Add the new function for USB drive detection
|
|
function Get-USBDrives {
|
|
Get-WmiObject Win32_DiskDrive | Where-Object {
|
|
($_.MediaType -eq 'Removable Media' -or $_.MediaType -eq 'External hard disk media') -and
|
|
$_.InterfaceType -eq 'USB'
|
|
} | ForEach-Object {
|
|
$size = [math]::Round($_.Size / 1GB, 2)
|
|
$serialNumber = if ($_.SerialNumber) { $_.SerialNumber.Trim() } else { "N/A" }
|
|
@{
|
|
IsSelected = $false
|
|
Model = $_.Model.Trim()
|
|
SerialNumber = $serialNumber
|
|
Size = $size
|
|
DriveIndex = $_.Index
|
|
}
|
|
}
|
|
}
|
|
|
|
# Some default values
|
|
$defaultISOPath = ""
|
|
$defaultWindowsRelease = 11 # numeric
|
|
$defaultWindowsArch = "x64"
|
|
$defaultWindowsLang = "en-us"
|
|
$defaultWindowsSKU = "Pro"
|
|
$defaultMediaType = "Consumer" # updated value
|
|
$defaultOptionalFeatures = ""
|
|
$defaultProductKey = ""
|
|
$defaultFFUPrefix = "_FFU" # <-- new default for VM Name Prefix
|
|
|
|
# Large list from the ValidateSet in BuildFFUVM.ps1 ($OptionalFeatures parameter)
|
|
$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"
|
|
)
|
|
|
|
$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','Standard',
|
|
'Standard (Desktop Experience)','Datacenter','Datacenter (Desktop Experience)'
|
|
)
|
|
|
|
# Full list of Windows releases (if ISO path != blank)
|
|
$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 }
|
|
)
|
|
|
|
# Subset for MCT (if ISO path is blank)
|
|
$mctWindowsReleases = @(
|
|
[PSCustomObject]@{ Display = "Windows 10"; Value = 10 },
|
|
[PSCustomObject]@{ Display = "Windows 11"; Value = 11 }
|
|
)
|
|
|
|
# Windows version sets
|
|
$windowsVersionMap = @{
|
|
10 = @("22H2")
|
|
11 = @("22H2","23H2","24H2")
|
|
2016 = @("1607")
|
|
2019 = @("1809")
|
|
2022 = @("21H2")
|
|
2025 = @("24H2")
|
|
}
|
|
|
|
# --------------------------------------------------------------------------
|
|
|
|
function Get-UIConfig {
|
|
# --- Build Tab Values ---
|
|
$ffuDevPath = $window.FindName('txtFFUDevPath').Text
|
|
$customFFUNameTemplate = $window.FindName('txtCustomFFUNameTemplate').Text
|
|
$ffuCaptureLocation = $window.FindName('txtFFUCaptureLocation').Text
|
|
$shareName = $window.FindName('txtShareName').Text
|
|
$username = $window.FindName('txtUsername').Text
|
|
|
|
# General Build Options (Build tab WrapPanel)
|
|
$buildUSB = $window.FindName('chkBuildUSBDrive').IsChecked
|
|
$compactOS = $window.FindName('chkCompactOS').IsChecked
|
|
$optimize = $window.FindName('chkOptimize').IsChecked
|
|
$createCapture = $window.FindName('chkCreateCaptureMedia').IsChecked
|
|
$createDeployMedia = $window.FindName('chkCreateDeploymentMedia').IsChecked
|
|
|
|
# Build USB Drive Section (new)
|
|
$buildUSB_USB = $window.FindName('chkBuildUSBDrive').IsChecked
|
|
$promptExt = $window.FindName('chkPromptExternalHardDiskMedia').IsChecked
|
|
$allowExt = $window.FindName('chkAllowExternalHardDiskMedia').IsChecked
|
|
|
|
# USB Drive Modification group (Build tab right column in new section)
|
|
$copyAutopilot = $window.FindName('chkCopyAutopilot').IsChecked
|
|
$copyUnattend = $window.FindName('chkCopyUnattend').IsChecked
|
|
$copyPPKG = $window.FindName('chkCopyPPKG').IsChecked
|
|
|
|
# --- Hyper-V Settings (from Hyper-V tab) ---
|
|
$cmbVMSwitch = $window.FindName('cmbVMSwitchName')
|
|
$vmSwitchName = $cmbVMSwitch.SelectedItem
|
|
if ($vmSwitchName -eq 'Other') { $vmSwitchName = $window.FindName('txtCustomVMSwitchName').Text }
|
|
$vmHostIPAddress = $window.FindName('txtVMHostIPAddress').Text
|
|
[int64]$diskSizeInGB = [int64]$window.FindName('txtDiskSize').Text
|
|
$diskSize = $diskSizeInGB * 1GB
|
|
[int64]$memoryInGB = [int64]$window.FindName('txtMemory').Text
|
|
$memory = $memoryInGB * 1GB
|
|
[int]$processors = [int]$window.FindName('txtProcessors').Text
|
|
$vmLocation = $window.FindName('txtVMLocation').Text
|
|
$logicalSectorObj = $window.FindName('cmbLogicalSectorSize').SelectedItem
|
|
$logicalSectorSize = [int]$logicalSectorObj.Content
|
|
|
|
# <-- NEW: retrieve FFUPrefix from the new textbox (VM Name Prefix)
|
|
$ffuPrefix = $window.FindName('txtVMNamePrefix').Text
|
|
|
|
# --- Windows Settings tab ---
|
|
$wrItem = $window.FindName('cmbWindowsRelease').SelectedItem
|
|
$windowsRelease = if ($wrItem -and $wrItem.Value) { [int]$wrItem.Value } else { 10 }
|
|
$windowsVersion = $window.FindName('cmbWindowsVersion').SelectedItem
|
|
$windowsArch = $window.FindName('cmbWindowsArch').SelectedItem
|
|
$windowsLang = $window.FindName('cmbWindowsLang').SelectedItem
|
|
$windowsSKU = $window.FindName('cmbWindowsSKU').SelectedItem
|
|
$mediaType = $window.FindName('cmbMediaType').SelectedItem
|
|
$productKey = $window.FindName('txtProductKey').Text
|
|
$isoPath = $window.FindName('txtISOPath').Text
|
|
|
|
# --- M365 Apps/Office tab ---
|
|
$installOffice = $window.FindName('chkInstallOffice').IsChecked
|
|
$officePath = $window.FindName('txtOfficePath').Text
|
|
$copyOfficeConfig = $window.FindName('chkCopyOfficeConfigXML').IsChecked
|
|
$officeConfigXMLFile = $window.FindName('txtOfficeConfigXMLFilePath').Text
|
|
|
|
# --- Drivers tab ---
|
|
$installDrivers = $window.FindName('chkInstallDrivers').IsChecked
|
|
$copyDrivers = $window.FindName('chkCopyDrivers').IsChecked
|
|
$downloadDrivers = $window.FindName('chkDownloadDrivers').IsChecked
|
|
$make = $window.FindName('cmbMake').SelectedItem
|
|
$model = $window.FindName('cmbModel').Text
|
|
$driversFolder = $window.FindName('txtDriversFolder').Text
|
|
$peDriversFolder = $window.FindName('txtPEDriversFolder').Text
|
|
$copyPEDrivers = $window.FindName('chkCopyPEDrivers').IsChecked
|
|
|
|
# --- Updates tab ---
|
|
$updateLatestCU = $window.FindName('chkUpdateLatestCU').IsChecked
|
|
$updateLatestNet = $window.FindName('chkUpdateLatestNet').IsChecked
|
|
$updateLatestDefender = $window.FindName('chkUpdateLatestDefender').IsChecked
|
|
$updateEdge = $window.FindName('chkUpdateEdge').IsChecked
|
|
$updateOneDrive = $window.FindName('chkUpdateOneDrive').IsChecked
|
|
$updateLatestMSRT = $window.FindName('chkUpdateLatestMSRT').IsChecked
|
|
$updatePreviewCU = $window.FindName('chkUpdatePreviewCU').IsChecked
|
|
|
|
# --- Applications tab ---
|
|
$installApps = $window.FindName('chkInstallApps').IsChecked
|
|
|
|
# Add USB drive selection to config
|
|
$selectedUSBDrives = @{}
|
|
$window.FindName('lstUSBDrives').Items | Where-Object { $_.IsSelected } | ForEach-Object {
|
|
$selectedUSBDrives[$_.Model] = $_.SerialNumber
|
|
}
|
|
|
|
# Build configuration hashtable (unsorted)
|
|
$config = [ordered]@{
|
|
AllowExternalHardDiskMedia = $allowExt
|
|
BuildUSBDrive = $buildUSB_USB
|
|
CompactOS = $compactOS
|
|
CopyAutopilot = $copyAutopilot
|
|
CopyOfficeConfigXML = $copyOfficeConfig
|
|
CopyPEDrivers = $copyPEDrivers
|
|
CopyPPKG = $copyPPKG
|
|
CopyUnattend = $copyUnattend
|
|
CreateCaptureMedia = $createCapture
|
|
CreateDeploymentMedia = $createDeployMedia
|
|
CleanupAppsISO = $window.FindName('chkCleanupAppsISO').IsChecked
|
|
CleanupCaptureISO = $window.FindName('chkCleanupCaptureISO').IsChecked
|
|
CleanupDeployISO = $window.FindName('chkCleanupDeployISO').IsChecked
|
|
CleanupDrivers = $window.FindName('chkCleanupDrivers').IsChecked
|
|
Disksize = $diskSize
|
|
DownloadDrivers = $downloadDrivers
|
|
EnablePromptExternalHardDiskMedia = $promptExt
|
|
FFUCaptureLocation = $ffuCaptureLocation
|
|
FFUDevelopmentPath = $ffuDevPath
|
|
ISOPath = $isoPath # <-- NEW: Add Windows ISO Path to config
|
|
MediaType = $mediaType
|
|
Make = $make
|
|
Model = $model
|
|
OfficeConfigXMLFile = $officeConfigXMLFile
|
|
OfficePath = $officePath
|
|
OptionalFeatures = $window.FindName('txtOptionalFeatures').Text
|
|
PEDriversFolder = $peDriversFolder
|
|
ProductKey = $productKey
|
|
Processors = $processors
|
|
RemoveFFU = $window.FindName('chkRemoveFFU').IsChecked
|
|
UpdateEdge = $updateEdge
|
|
UpdateLatestCU = $updateLatestCU
|
|
UpdateLatestDefender = $updateLatestDefender
|
|
UpdateLatestMSRT = $updateLatestMSRT
|
|
UpdateLatestNet = $updateLatestNet
|
|
UpdateOneDrive = $updateOneDrive
|
|
UpdatePreviewCU = $updatePreviewCU
|
|
VMHostIPAddress = $vmHostIPAddress
|
|
VMLocation = $vmLocation
|
|
VMSwitchName = $vmSwitchName
|
|
LogicalSectorSizeBytes = $logicalSectorSize
|
|
Memory = $memory
|
|
WindowsArch = $windowsArch
|
|
WindowsLang = $windowsLang
|
|
WindowsRelease = $windowsRelease
|
|
WindowsSKU = $windowsSKU
|
|
WindowsVersion = $windowsVersion
|
|
FFUPrefix = $ffuPrefix # <-- new option for VM Name Prefix
|
|
USBDriveList = $selectedUSBDrives # Add USB drive selection
|
|
}
|
|
|
|
# Sort the configuration hashtable alphabetically by key
|
|
$sortedConfig = [ordered]@{}
|
|
foreach ($key in ($config.Keys | Sort-Object)) {
|
|
$sortedConfig[$key] = $config[$key]
|
|
}
|
|
return $sortedConfig
|
|
}
|
|
|
|
function UpdateWindowsReleaseList {
|
|
param([string]$isoPath)
|
|
if (-not $script:cmbWindowsRelease) { return }
|
|
$oldItem = $script:cmbWindowsRelease.SelectedItem
|
|
$script:cmbWindowsRelease.Items.Clear()
|
|
$script:cmbWindowsRelease.DisplayMemberPath = 'Display'
|
|
$script:cmbWindowsRelease.SelectedValuePath = 'Value'
|
|
if ([string]::IsNullOrEmpty($isoPath)) {
|
|
foreach ($rel in $mctWindowsReleases) { $script:cmbWindowsRelease.Items.Add($rel) | Out-Null }
|
|
}
|
|
else {
|
|
foreach ($rel in $allWindowsReleases) { $script:cmbWindowsRelease.Items.Add($rel) | Out-Null }
|
|
}
|
|
if ($oldItem) {
|
|
$reSelect = $script:cmbWindowsRelease.Items | Where-Object { $_.Value -eq $oldItem.Value }
|
|
if ($reSelect) { $script:cmbWindowsRelease.SelectedItem = $reSelect }
|
|
else { $script:cmbWindowsRelease.SelectedIndex = 0 }
|
|
}
|
|
else { $script:cmbWindowsRelease.SelectedIndex = 0 }
|
|
}
|
|
|
|
function UpdateWindowsVersionCombo {
|
|
param(
|
|
[int]$selectedRelease,
|
|
[string]$isoPath
|
|
)
|
|
$combo = $window.FindName('cmbWindowsVersion')
|
|
if (-not $combo) { return }
|
|
$combo.Items.Clear()
|
|
if (-not $windowsVersionMap.ContainsKey($selectedRelease)) {
|
|
$combo.IsEnabled = $false
|
|
return
|
|
}
|
|
$validVersions = $windowsVersionMap[$selectedRelease]
|
|
if ([string]::IsNullOrEmpty($isoPath)) {
|
|
switch ($selectedRelease) {
|
|
10 { $default = "22H2" }
|
|
11 { $default = "24H2" }
|
|
2016 { $default = "1607" }
|
|
2019 { $default = "1809" }
|
|
2022 { $default = "21H2" }
|
|
2025 { $default = "24H2" }
|
|
default { $default = $validVersions[0] }
|
|
}
|
|
$combo.Items.Add($default) | Out-Null
|
|
$combo.SelectedIndex = 0
|
|
$combo.IsEnabled = $false
|
|
}
|
|
else {
|
|
foreach ($v in $validVersions) { [void]$combo.Items.Add($v) }
|
|
if ($selectedRelease -eq 11 -and $validVersions -contains "24H2") { $combo.SelectedItem = "24H2" }
|
|
else { $combo.SelectedIndex = 0 }
|
|
$combo.IsEnabled = $true
|
|
}
|
|
}
|
|
|
|
$script:RefreshWindowsUI = {
|
|
param([string]$isoPath)
|
|
UpdateWindowsReleaseList -isoPath $isoPath
|
|
$selItem = $script:cmbWindowsRelease.SelectedItem
|
|
if ($selItem -and $selItem.Value -is [int]) { $selectedRelease = [int]$selItem.Value }
|
|
else { $selectedRelease = 10 }
|
|
UpdateWindowsVersionCombo -selectedRelease $selectedRelease -isoPath $isoPath
|
|
}
|
|
|
|
Add-Type -AssemblyName WindowsBase
|
|
Add-Type -AssemblyName PresentationCore,PresentationFramework
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
|
|
# Load XAML
|
|
$xamlPath = Join-Path $PSScriptRoot "BuildFFUVM_UI.xaml"
|
|
if (-not (Test-Path $xamlPath)) {
|
|
Write-Error "XAML file not found: $xamlPath"
|
|
return
|
|
}
|
|
$xamlString = Get-Content $xamlPath -Raw
|
|
$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
|
|
$script:featureCheckBoxes = @{}
|
|
function UpdateOptionalFeaturesString {
|
|
$checkedFeatures = @()
|
|
foreach ($entry in $script:featureCheckBoxes.GetEnumerator()) {
|
|
if ($entry.Value.IsChecked) { $checkedFeatures += $entry.Key }
|
|
}
|
|
$window.FindName('txtOptionalFeatures').Text = $checkedFeatures -join ";"
|
|
}
|
|
function BuildFeaturesGrid {
|
|
param (
|
|
[System.Windows.FrameworkElement]$parent
|
|
)
|
|
$parent.Children.Clear()
|
|
$sortedFeatures = $allowedFeatures | Sort-Object
|
|
$rows = 10
|
|
$columns = [math]::Ceiling($sortedFeatures.Count / $rows)
|
|
$featuresGrid = New-Object System.Windows.Controls.Grid
|
|
$featuresGrid.Margin = "0,5,0,5"
|
|
$featuresGrid.ShowGridLines = $false
|
|
for ($r = 0; $r -lt $rows; $r++) {
|
|
$rowDef = New-Object System.Windows.Controls.RowDefinition
|
|
$rowDef.Height = 'Auto'
|
|
$featuresGrid.RowDefinitions.Add($rowDef) | Out-Null
|
|
}
|
|
for ($c = 0; $c -lt $columns; $c++) {
|
|
$colDef = New-Object System.Windows.Controls.ColumnDefinition
|
|
$colDef.Width = 'Auto'
|
|
$featuresGrid.ColumnDefinitions.Add($colDef) | Out-Null
|
|
}
|
|
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 })
|
|
$chk.Add_Unchecked({ UpdateOptionalFeaturesString })
|
|
$script:featureCheckBoxes[$featureName] = $chk
|
|
[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
|
|
}
|
|
|
|
# Variables for managing forced Install Apps state due to Updates
|
|
$script:installAppsForcedByUpdates = $false
|
|
$script:prevInstallAppsStateBeforeUpdates = $null
|
|
|
|
# Define the function in script scope to update Install Apps based on Updates tab
|
|
$script:UpdateInstallAppsBasedOnUpdates = {
|
|
$anyUpdateChecked = $window.FindName('chkUpdateLatestDefender').IsChecked -or $window.FindName('chkUpdateEdge').IsChecked -or $window.FindName('chkUpdateOneDrive').IsChecked -or $window.FindName('chkUpdateLatestMSRT').IsChecked
|
|
if ($anyUpdateChecked) {
|
|
if (-not $script:installAppsForcedByUpdates) {
|
|
$script:prevInstallAppsStateBeforeUpdates = $window.FindName('chkInstallApps').IsChecked
|
|
$script:installAppsForcedByUpdates = $true
|
|
}
|
|
$window.FindName('chkInstallApps').IsChecked = $true
|
|
$window.FindName('chkInstallApps').IsEnabled = $false
|
|
} else {
|
|
if ($script:installAppsForcedByUpdates) {
|
|
$window.FindName('chkInstallApps').IsChecked = $script:prevInstallAppsStateBeforeUpdates
|
|
$script:installAppsForcedByUpdates = $false
|
|
$script:prevInstallAppsStateBeforeUpdates = $null
|
|
}
|
|
$window.FindName('chkInstallApps').IsEnabled = $true
|
|
}
|
|
}
|
|
|
|
$window.Add_Loaded({
|
|
$script:cmbWindowsRelease = $window.FindName('cmbWindowsRelease')
|
|
$script:cmbWindowsVersion = $window.FindName('cmbWindowsVersion')
|
|
$script:txtISOPath = $window.FindName('txtISOPath')
|
|
& $script:RefreshWindowsUI($defaultISOPath)
|
|
$script:txtISOPath.Add_TextChanged({ & $script:RefreshWindowsUI($script:txtISOPath.Text) })
|
|
$script:cmbWindowsRelease.Add_SelectionChanged({
|
|
$selItem = $script:cmbWindowsRelease.SelectedItem
|
|
if ($selItem -and $selItem.Value) { UpdateWindowsVersionCombo -selectedRelease $selItem.Value -isoPath $script:txtISOPath.Text }
|
|
})
|
|
$script:btnBrowseISO = $window.FindName('btnBrowseISO')
|
|
$script:btnBrowseISO.Add_Click({
|
|
$ofd = New-Object System.Windows.Forms.OpenFileDialog
|
|
$ofd.Filter = "ISO files (*.iso)|*.iso"
|
|
$ofd.Title = "Select Windows ISO File"
|
|
if ($ofd.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $script:txtISOPath.Text = $ofd.FileName }
|
|
})
|
|
# Home tab (renamed from Basic) displays static welcome text.
|
|
# Build tab defaults
|
|
$window.FindName('txtFFUDevPath').Text = $FFUDevelopmentPath
|
|
$window.FindName('txtCustomFFUNameTemplate').Text = "{WindowsRelease}_{WindowsVersion}_{SKU}_{yyyy}-{MM}-{dd}_{HH}{mm}"
|
|
$window.FindName('txtFFUCaptureLocation').Text = (Join-Path $FFUDevelopmentPath "FFU")
|
|
$window.FindName('txtShareName').Text = "FFUCaptureShare"
|
|
$window.FindName('txtUsername').Text = "ffu_user"
|
|
# Set VM Location default to $FFUDevelopmentPath\VM
|
|
$window.FindName('txtVMLocation').Text = (Join-Path $FFUDevelopmentPath "VM")
|
|
# <-- NEW: Set the default for the new VM Name Prefix textbox on the Hyper-V Settings tab
|
|
$window.FindName('txtVMNamePrefix').Text = $defaultFFUPrefix
|
|
# Hyper-V Settings: Populate defaults (Share Name and Username now on Build, so only populate remaining fields)
|
|
$script:vmSwitchMap = @{}
|
|
$script:allSwitches = Get-VMSwitch -ErrorAction SilentlyContinue
|
|
$script:cmbVMSwitchName = $window.FindName('cmbVMSwitchName')
|
|
foreach ($sw in $script:allSwitches) {
|
|
$script:cmbVMSwitchName.Items.Add($sw.Name) | Out-Null
|
|
$na = Get-NetAdapter -ErrorAction SilentlyContinue | Where-Object { $_.Name -like "*($($sw.Name))*" }
|
|
if ($na) {
|
|
$netIPs = Get-NetIPAddress -InterfaceIndex $na.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
|
|
$validIPs = $netIPs | Where-Object { $_.IPAddress -notlike '169.254.*' -and $_.IPAddress }
|
|
if ($validIPs) { $script:vmSwitchMap[$sw.Name] = ($validIPs | Select-Object -First 1).IPAddress }
|
|
}
|
|
}
|
|
$script:cmbVMSwitchName.Items.Add('Other') | Out-Null
|
|
if ($script:cmbVMSwitchName.Items.Count -gt 0) {
|
|
if ($script:allSwitches.Count -gt 0) {
|
|
$script:cmbVMSwitchName.SelectedIndex = 0
|
|
$first = $script:cmbVMSwitchName.SelectedItem
|
|
if ($script:vmSwitchMap.ContainsKey($first)) { $window.FindName('txtVMHostIPAddress').Text = $script:vmSwitchMap[$first] }
|
|
else { $window.FindName('txtVMHostIPAddress').Text = '' }
|
|
}
|
|
else {
|
|
$script:cmbVMSwitchName.SelectedItem = 'Other'
|
|
$window.FindName('txtCustomVMSwitchName').Visibility = 'Visible'
|
|
}
|
|
}
|
|
$script:cmbVMSwitchName.Add_SelectionChanged({
|
|
if ($_.AddedItems -contains 'Other') {
|
|
$window.FindName('txtCustomVMSwitchName').Visibility = 'Visible'
|
|
$window.FindName('txtVMHostIPAddress').Text = ''
|
|
}
|
|
else {
|
|
$window.FindName('txtCustomVMSwitchName').Visibility = 'Collapsed'
|
|
$sel = $_.AddedItems[0]
|
|
if ($script:vmSwitchMap.ContainsKey($sel)) { $window.FindName('txtVMHostIPAddress').Text = $script:vmSwitchMap[$sel] }
|
|
else { $window.FindName('txtVMHostIPAddress').Text = '' }
|
|
}
|
|
})
|
|
# Windows Arch, Lang, SKU, etc.
|
|
$script:cmbWindowsArch = $window.FindName('cmbWindowsArch')
|
|
foreach ($a in 'x86','x64','arm64') { [void]$script:cmbWindowsArch.Items.Add($a) }
|
|
$script:cmbWindowsArch.SelectedItem = $defaultWindowsArch
|
|
$script:cmbWindowsLang = $window.FindName('cmbWindowsLang')
|
|
$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'
|
|
)
|
|
foreach ($lang in $allowedLangs) { [void]$script:cmbWindowsLang.Items.Add($lang) }
|
|
$script:cmbWindowsLang.SelectedItem = $defaultWindowsLang
|
|
$script:cmbWindowsSKU = $window.FindName('cmbWindowsSKU')
|
|
$script:cmbWindowsSKU.Items.Clear()
|
|
foreach ($sku in $skuList) { [void]$script:cmbWindowsSKU.Items.Add($sku) }
|
|
$script:cmbWindowsSKU.SelectedItem = $defaultWindowsSKU
|
|
$script:cmbMediaType = $window.FindName('cmbMediaType')
|
|
foreach ($mt in "Consumer","Business") { [void]$script:cmbMediaType.Items.Add($mt) } # updated options
|
|
$script:cmbMediaType.SelectedItem = $defaultMediaType
|
|
$script:txtOptionalFeatures = $window.FindName('txtOptionalFeatures')
|
|
$script:txtOptionalFeatures.Text = $defaultOptionalFeatures
|
|
$window.FindName('txtProductKey').Text = $defaultProductKey
|
|
# Drivers tab
|
|
$script:chkDownloadDrivers = $window.FindName('chkDownloadDrivers')
|
|
$script:cmbMake = $window.FindName('cmbMake')
|
|
$script:cmbModel = $window.FindName('cmbModel')
|
|
$script:spMakeModelSection = $window.FindName('spMakeModelSection')
|
|
$makeList = @('Microsoft','Dell','HP','Lenovo')
|
|
foreach ($m in $makeList) { [void]$script:cmbMake.Items.Add($m) }
|
|
if ($script:cmbMake.Items.Count -gt 0) { $script:cmbMake.SelectedIndex = 0 }
|
|
$script:chkDownloadDrivers.Add_Checked({
|
|
$script:cmbMake.Visibility = 'Visible'
|
|
$script:cmbModel.Visibility = 'Visible'
|
|
$script:spMakeModelSection.Visibility = 'Visible'
|
|
})
|
|
$script:chkDownloadDrivers.Add_Unchecked({
|
|
$script:cmbMake.Visibility = 'Collapsed'
|
|
$script:cmbModel.Visibility = 'Collapsed'
|
|
$script:spMakeModelSection.Visibility = 'Collapsed'
|
|
})
|
|
# Office interplay
|
|
$script:chkInstallOffice = $window.FindName('chkInstallOffice')
|
|
$script:chkInstallApps = $window.FindName('chkInstallApps')
|
|
$script:installAppsCheckedByOffice = $false
|
|
$script:OfficePathStackPanel = $window.FindName('OfficePathStackPanel')
|
|
$script:OfficePathGrid = $window.FindName('OfficePathGrid')
|
|
$script:CopyOfficeConfigXMLStackPanel = $window.FindName('CopyOfficeConfigXMLStackPanel')
|
|
$script:OfficeConfigurationXMLFileStackPanel = $window.FindName('OfficeConfigurationXMLFileStackPanel')
|
|
$script:OfficeConfigurationXMLFileGrid = $window.FindName('OfficeConfigurationXMLFileGrid')
|
|
$script:chkCopyOfficeConfigXML = $window.FindName('chkCopyOfficeConfigXML')
|
|
if ($script:chkInstallOffice.IsChecked) {
|
|
$script:OfficePathStackPanel.Visibility = 'Visible'
|
|
$script:OfficePathGrid.Visibility = 'Visible'
|
|
$script:CopyOfficeConfigXMLStackPanel.Visibility = 'Visible'
|
|
}
|
|
else {
|
|
$script:OfficePathStackPanel.Visibility = 'Collapsed'
|
|
$script:OfficePathGrid.Visibility = 'Collapsed'
|
|
$script:CopyOfficeConfigXMLStackPanel.Visibility = 'Collapsed'
|
|
$script:OfficeConfigurationXMLFileStackPanel.Visibility = 'Collapsed'
|
|
$script:OfficeConfigurationXMLFileGrid.Visibility = 'Collapsed'
|
|
}
|
|
$script:chkInstallOffice.Add_Checked({
|
|
if (-not $script:chkInstallApps.IsChecked) {
|
|
$script:chkInstallApps.IsChecked = $true
|
|
$script:installAppsCheckedByOffice = $true
|
|
}
|
|
$script:chkInstallApps.IsEnabled = $false
|
|
$script:OfficePathStackPanel.Visibility = 'Visible'
|
|
$script:OfficePathGrid.Visibility = 'Visible'
|
|
$script:CopyOfficeConfigXMLStackPanel.Visibility = 'Visible'
|
|
})
|
|
$script:chkInstallOffice.Add_Unchecked({
|
|
if ($script:installAppsCheckedByOffice) {
|
|
$script:chkInstallApps.IsChecked = $false
|
|
$script:installAppsCheckedByOffice = $false
|
|
}
|
|
$script:chkInstallApps.IsEnabled = $true
|
|
$script:OfficePathStackPanel.Visibility = 'Collapsed'
|
|
$script:OfficePathGrid.Visibility = 'Collapsed'
|
|
$script:CopyOfficeConfigXMLStackPanel.Visibility = 'Collapsed'
|
|
$script:OfficeConfigurationXMLFileStackPanel.Visibility = 'Collapsed'
|
|
$script:OfficeConfigurationXMLFileGrid.Visibility = 'Collapsed'
|
|
})
|
|
$script:chkCopyOfficeConfigXML.Add_Checked({
|
|
$script:OfficeConfigurationXMLFileStackPanel.Visibility = 'Visible'
|
|
$script:OfficeConfigurationXMLFileGrid.Visibility = 'Visible'
|
|
})
|
|
$script:chkCopyOfficeConfigXML.Add_Unchecked({
|
|
$script:OfficeConfigurationXMLFileStackPanel.Visibility = 'Collapsed'
|
|
$script:OfficeConfigurationXMLFileGrid.Visibility = 'Collapsed'
|
|
})
|
|
# Build dynamic multi-column checkboxes for optional features in Windows Settings tab
|
|
$script:featuresPanel = $window.FindName('stackFeaturesContainer')
|
|
if ($script:featuresPanel) { BuildFeaturesGrid -parent $script:featuresPanel }
|
|
# Variables for managing forced Install Apps state due to Updates
|
|
$script:installAppsForcedByUpdates = $false
|
|
$script:prevInstallAppsStateBeforeUpdates = $null
|
|
# Define the function in script scope to update Install Apps based on Updates tab
|
|
$script:UpdateInstallAppsBasedOnUpdates = {
|
|
$anyUpdateChecked = $window.FindName('chkUpdateLatestDefender').IsChecked -or $window.FindName('chkUpdateEdge').IsChecked -or $window.FindName('chkUpdateOneDrive').IsChecked -or $window.FindName('chkUpdateLatestMSRT').IsChecked
|
|
if ($anyUpdateChecked) {
|
|
if (-not $script:installAppsForcedByUpdates) {
|
|
$script:prevInstallAppsStateBeforeUpdates = $window.FindName('chkInstallApps').IsChecked
|
|
$script:installAppsForcedByUpdates = $true
|
|
}
|
|
$window.FindName('chkInstallApps').IsChecked = $true
|
|
$window.FindName('chkInstallApps').IsEnabled = $false
|
|
} else {
|
|
if ($script:installAppsForcedByUpdates) {
|
|
$window.FindName('chkInstallApps').IsChecked = $script:prevInstallAppsStateBeforeUpdates
|
|
$script:installAppsForcedByUpdates = $false
|
|
$script:prevInstallAppsStateBeforeUpdates = $null
|
|
}
|
|
$window.FindName('chkInstallApps').IsEnabled = $true
|
|
}
|
|
}
|
|
# Add event handlers for Updates tab checkboxes to update Install Apps state
|
|
$window.FindName('chkUpdateLatestDefender').Add_Checked({ & $script:UpdateInstallAppsBasedOnUpdates })
|
|
$window.FindName('chkUpdateLatestDefender').Add_Unchecked({ & $script:UpdateInstallAppsBasedOnUpdates })
|
|
$window.FindName('chkUpdateEdge').Add_Checked({ & $script:UpdateInstallAppsBasedOnUpdates })
|
|
$window.FindName('chkUpdateEdge').Add_Unchecked({ & $script:UpdateInstallAppsBasedOnUpdates })
|
|
$window.FindName('chkUpdateOneDrive').Add_Checked({ & $script:UpdateInstallAppsBasedOnUpdates })
|
|
$window.FindName('chkUpdateOneDrive').Add_Unchecked({ & $script:UpdateInstallAppsBasedOnUpdates })
|
|
$window.FindName('chkUpdateLatestMSRT').Add_Checked({ & $script:UpdateInstallAppsBasedOnUpdates })
|
|
$window.FindName('chkUpdateLatestMSRT').Add_Unchecked({ & $script:UpdateInstallAppsBasedOnUpdates })
|
|
# Add interplay between Latest CU and Preview CU checkboxes
|
|
$script:chkLatestCU = $window.FindName('chkUpdateLatestCU')
|
|
$script:chkPreviewCU = $window.FindName('chkUpdatePreviewCU')
|
|
|
|
$script:chkLatestCU.Add_Checked({
|
|
$script:chkPreviewCU.IsEnabled = $false
|
|
})
|
|
$script:chkLatestCU.Add_Unchecked({
|
|
$script:chkPreviewCU.IsEnabled = $true
|
|
})
|
|
|
|
$script:chkPreviewCU.Add_Checked({
|
|
$script:chkLatestCU.IsEnabled = $false
|
|
})
|
|
$script:chkPreviewCU.Add_Unchecked({
|
|
$script:chkLatestCU.IsEnabled = $true
|
|
})
|
|
|
|
# Add USB Drive Detection handler
|
|
$script:btnCheckUSBDrives = $window.FindName('btnCheckUSBDrives')
|
|
$script:lstUSBDrives = $window.FindName('lstUSBDrives')
|
|
$script:chkSelectAllUSBDrives = $window.FindName('chkSelectAllUSBDrives')
|
|
|
|
$script:btnCheckUSBDrives.Add_Click({
|
|
$script:lstUSBDrives.Items.Clear()
|
|
$usbDrives = Get-USBDrives
|
|
foreach ($drive in $usbDrives) {
|
|
$script:lstUSBDrives.Items.Add([PSCustomObject]$drive)
|
|
}
|
|
if ($script:lstUSBDrives.Items.Count -gt 0) {
|
|
$script:lstUSBDrives.SelectedIndex = 0
|
|
}
|
|
})
|
|
|
|
# Handle Select All checkbox
|
|
$script:chkSelectAllUSBDrives.Add_Checked({
|
|
foreach ($item in $script:lstUSBDrives.Items) {
|
|
$item.IsSelected = $true
|
|
}
|
|
$script:lstUSBDrives.Items.Refresh()
|
|
})
|
|
|
|
$script:chkSelectAllUSBDrives.Add_Unchecked({
|
|
foreach ($item in $script:lstUSBDrives.Items) {
|
|
$item.IsSelected = $false
|
|
}
|
|
$script:lstUSBDrives.Items.Refresh()
|
|
})
|
|
|
|
# Add keyboard handler
|
|
$script:lstUSBDrives.Add_KeyDown({
|
|
param($sender, $e)
|
|
if ($e.Key -eq 'Space') {
|
|
$selectedItem = $script:lstUSBDrives.SelectedItem
|
|
if ($selectedItem) {
|
|
$selectedItem.IsSelected = !$selectedItem.IsSelected
|
|
$script:lstUSBDrives.Items.Refresh()
|
|
# Update Select All checkbox state
|
|
$allSelected = -not ($script:lstUSBDrives.Items | Where-Object { -not $_.IsSelected })
|
|
$script:chkSelectAllUSBDrives.IsChecked = $allSelected
|
|
}
|
|
}
|
|
})
|
|
|
|
# Add selection change handler
|
|
$script:lstUSBDrives.Add_SelectionChanged({
|
|
param($sender, $e)
|
|
# Update Select All checkbox state
|
|
$allSelected = -not ($script:lstUSBDrives.Items | Where-Object { -not $_.IsSelected })
|
|
$script:chkSelectAllUSBDrives.IsChecked = $allSelected
|
|
})
|
|
|
|
# Add handler to show/hide USB drive controls based on Build USB Drive checkbox
|
|
$script:chkBuildUSBDrive = $window.FindName('chkBuildUSBDrive')
|
|
$script:usbPanel = ($window.FindName('btnCheckUSBDrives').Parent.Parent) # Get the outer Grid instead of immediate parent
|
|
$script:usbPanel.Visibility = if ($script:chkBuildUSBDrive.IsChecked) { 'Visible' } else { 'Collapsed' }
|
|
|
|
$script:chkBuildUSBDrive.Add_Checked({
|
|
$script:usbPanel.Visibility = 'Visible'
|
|
})
|
|
|
|
$script:chkBuildUSBDrive.Add_Unchecked({
|
|
$script:lstUSBDrives.Items.Clear()
|
|
$script:chkSelectAllUSBDrives.IsChecked = $false
|
|
$script:usbPanel.Visibility = 'Collapsed'
|
|
})
|
|
|
|
# Add commands for keyboard selection
|
|
$script:lstUSBDrives = $window.FindName('lstUSBDrives')
|
|
$script:lstUSBDrives.Add_KeyDown({
|
|
param($sender, $e)
|
|
if ($e.Key -eq 'Space') {
|
|
$selectedItem = $script:lstUSBDrives.SelectedItem
|
|
if ($selectedItem) {
|
|
$selectedItem.IsSelected = !$selectedItem.IsSelected
|
|
# Update Select All checkbox state
|
|
$allSelected = -not ($script:lstUSBDrives.Items | Where-Object { -not $_.IsSelected })
|
|
$script:chkSelectAllUSBDrives.IsChecked = $allSelected
|
|
}
|
|
}
|
|
})
|
|
|
|
# Add handler for item selection changed
|
|
$script:lstUSBDrives.Add_SelectionChanged({
|
|
param($sender, $e)
|
|
# Update Select All checkbox state
|
|
$allSelected = -not ($script:lstUSBDrives.Items | Where-Object { -not $_.IsSelected })
|
|
$script:chkSelectAllUSBDrives.IsChecked = $allSelected
|
|
})
|
|
})
|
|
|
|
# Button: Build FFU
|
|
$btnRun = $window.FindName('btnRun')
|
|
$btnRun.Add_Click({
|
|
try {
|
|
$progressBar = $window.FindName('progressBar')
|
|
$txtStatus = $window.FindName('txtStatus')
|
|
$progressBar.Visibility = 'Visible'
|
|
$txtStatus.Text = "Starting FFU build..."
|
|
$config = Get-UIConfig
|
|
$configFilePath = Join-Path $config.FFUDevelopmentPath "FFUConfig.json"
|
|
$config | ConvertTo-Json -Depth 10 | Set-Content $configFilePath -Encoding UTF8
|
|
$txtStatus.Text = "Executing BuildFFUVM script with config file..."
|
|
& "$PSScriptRoot\BuildFFUVM.ps1" -ConfigFile $configFilePath -Verbose
|
|
if ($config.InstallOffice -and $config.OfficeConfigXMLFile) {
|
|
Copy-Item -Path $config.OfficeConfigXMLFile -Destination $config.OfficePath -Force
|
|
$txtStatus.Text = "Office Configuration XML file copied successfully."
|
|
}
|
|
$txtStatus.Text = "FFU build completed successfully."
|
|
}
|
|
catch {
|
|
[System.Windows.MessageBox]::Show("An error occurred: $_", "Error", "OK", "Error")
|
|
$window.FindName('txtStatus').Text = "FFU build failed."
|
|
}
|
|
finally {
|
|
$window.FindName('progressBar').Visibility = 'Collapsed'
|
|
}
|
|
})
|
|
|
|
# Button: Build Config
|
|
$btnBuildConfig = $window.FindName('btnBuildConfig')
|
|
$btnBuildConfig.Add_Click({
|
|
try {
|
|
$config = Get-UIConfig
|
|
$defaultConfigPath = Join-Path $config.FFUDevelopmentPath "config"
|
|
if (-not (Test-Path $defaultConfigPath)) {
|
|
New-Item -Path $defaultConfigPath -ItemType Directory -Force | Out-Null
|
|
}
|
|
$sfd = New-Object System.Windows.Forms.SaveFileDialog
|
|
$sfd.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
|
|
$sfd.Title = "Save Configuration File"
|
|
$sfd.InitialDirectory = $defaultConfigPath
|
|
$sfd.FileName = "FFUConfig.json"
|
|
if ($sfd.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
|
|
$savePath = $sfd.FileName
|
|
$config | ConvertTo-Json -Depth 10 | Set-Content $savePath -Encoding UTF8
|
|
[System.Windows.MessageBox]::Show("Configuration file saved to:`n$savePath", "Success", "OK", "Information")
|
|
}
|
|
}
|
|
catch {
|
|
[System.Windows.MessageBox]::Show("Error saving config file:`n$_","Error","OK","Error")
|
|
}
|
|
})
|
|
|
|
# Button: Load Config File
|
|
$btnLoadConfig = $window.FindName('btnLoadConfig')
|
|
$btnLoadConfig.Add_Click({
|
|
try {
|
|
$ofd = New-Object System.Windows.Forms.OpenFileDialog
|
|
$ofd.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
|
|
$ofd.Title = "Load Configuration File"
|
|
if ($ofd.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
|
|
$configContent = Get-Content -Path $ofd.FileName -Raw | ConvertFrom-Json
|
|
# Update Build tab values
|
|
$window.FindName('txtFFUDevPath').Text = $configContent.FFUDevelopmentPath
|
|
$window.FindName('txtCustomFFUNameTemplate').Text = $configContent.CustomFFUNameTemplate
|
|
$window.FindName('txtFFUCaptureLocation').Text = $configContent.FFUCaptureLocation
|
|
$window.FindName('txtShareName').Text = $configContent.ShareName
|
|
$window.FindName('txtUsername').Text = $configContent.Username
|
|
$window.FindName('chkBuildUSBDrive').IsChecked = $configContent.BuildUSBDrive
|
|
$window.FindName('chkCompactOS').IsChecked = $configContent.CompactOS
|
|
$window.FindName('chkOptimize').IsChecked = $configContent.Optimize
|
|
$window.FindName('chkPromptExternalHardDiskMedia').IsChecked = $configContent.EnablePromptExternalHardDiskMedia
|
|
$window.FindName('chkAllowExternalHardDiskMedia').IsChecked = $configContent.AllowExternalHardDiskMedia
|
|
$window.FindName('chkCreateCaptureMedia').IsChecked = $configContent.CreateCaptureMedia
|
|
$window.FindName('chkCreateDeploymentMedia').IsChecked = $configContent.CreateDeploymentMedia
|
|
# Post Build Cleanup group
|
|
$window.FindName('chkCleanupAppsISO').IsChecked = $configContent.CleanupAppsISO
|
|
$window.FindName('chkCleanupCaptureISO').IsChecked = $configContent.CleanupCaptureISO
|
|
$window.FindName('chkCleanupDeployISO').IsChecked = $configContent.CleanupDeployISO
|
|
$window.FindName('chkCleanupDrivers').IsChecked = $configContent.CleanupDrivers
|
|
$window.FindName('chkRemoveFFU').IsChecked = $configContent.RemoveFFU
|
|
# USB Drive Modification group (now in Build USB Drive section)
|
|
$window.FindName('chkCopyAutopilot').IsChecked = $configContent.CopyAutopilot
|
|
$window.FindName('chkCopyUnattend').IsChecked = $configContent.CopyUnattend
|
|
$window.FindName('chkCopyPPKG').IsChecked = $configContent.CopyPPKG
|
|
# Hyper-V Settings
|
|
$window.FindName('cmbVMSwitchName').SelectedItem = $configContent.VMSwitchName
|
|
$window.FindName('txtVMHostIPAddress').Text = $configContent.VMHostIPAddress
|
|
$window.FindName('txtDiskSize').Text = $configContent.Disksize / 1GB
|
|
$window.FindName('txtMemory').Text = $configContent.Memory / 1GB
|
|
$window.FindName('txtProcessors').Text = $configContent.Processors
|
|
$window.FindName('txtVMLocation').Text = $configContent.VMLocation
|
|
# <-- NEW: Update the VM Name Prefix textbox value during config load
|
|
$window.FindName('txtVMNamePrefix').Text = $configContent.FFUPrefix
|
|
$window.FindName('cmbLogicalSectorSize').SelectedItem = $configContent.LogicalSectorSizeBytes
|
|
# Windows Settings
|
|
$window.FindName('txtISOPath').Text = $configContent.ISOPath
|
|
$window.FindName('cmbWindowsRelease').SelectedItem = ($script:allWindowsReleases | Where-Object { $_.Value -eq $configContent.WindowsRelease })
|
|
$window.FindName('cmbWindowsVersion').SelectedItem = $configContent.WindowsVersion
|
|
$window.FindName('cmbWindowsArch').SelectedItem = $configContent.WindowsArch
|
|
$window.FindName('cmbWindowsLang').SelectedItem = $configContent.WindowsLang
|
|
$window.FindName('cmbWindowsSKU').SelectedItem = $configContent.WindowsSKU
|
|
$window.FindName('cmbMediaType').SelectedItem = $configContent.MediaType
|
|
$window.FindName('txtProductKey').Text = $configContent.ProductKey
|
|
# M365 Apps/Office tab
|
|
$window.FindName('chkInstallOffice').IsChecked = $configContent.InstallOffice
|
|
$window.FindName('txtOfficePath').Text = $configContent.OfficePath
|
|
$window.FindName('chkCopyOfficeConfigXML').IsChecked = $configContent.CopyOfficeConfigXML
|
|
$window.FindName('txtOfficeConfigXMLFilePath').Text = $configContent.OfficeConfigXMLFile
|
|
# Drivers tab
|
|
$window.FindName('chkInstallDrivers').IsChecked = $configContent.InstallDrivers
|
|
$window.FindName('chkDownloadDrivers').IsChecked = $configContent.DownloadDrivers
|
|
$window.FindName('chkCopyDrivers').IsChecked = $configContent.CopyDrivers
|
|
$window.FindName('cmbMake').SelectedItem = $configContent.Make
|
|
$window.FindName('cmbModel').Text = $configContent.Model
|
|
$window.FindName('txtDriversFolder').Text = $configContent.DriversFolder
|
|
$window.FindName('txtPEDriversFolder').Text = $configContent.PEDriversFolder
|
|
$window.FindName('chkCopyPEDrivers').IsChecked = $configContent.CopyPEDrivers
|
|
# Updates tab
|
|
$window.FindName('chkUpdateLatestCU').IsChecked = $configContent.UpdateLatestCU
|
|
$window.FindName('chkUpdateLatestNet').IsChecked = $configContent.UpdateLatestNet
|
|
$window.FindName('chkUpdateLatestDefender').IsChecked = $configContent.UpdateLatestDefender
|
|
$window.FindName('chkUpdateEdge').IsChecked = $configContent.UpdateEdge
|
|
$window.FindName('chkUpdateOneDrive').IsChecked = $configContent.UpdateOneDrive
|
|
$window.FindName('chkUpdateLatestMSRT').IsChecked = $configContent.UpdateLatestMSRT
|
|
$window.FindName('chkUpdatePreviewCU').IsChecked = $configContent.UpdatePreviewCU
|
|
# Applications tab
|
|
$window.FindName('chkInstallApps').IsChecked = $configContent.InstallApps
|
|
|
|
# Update USB Drive selection if present in config
|
|
if ($configContent.USBDriveList) {
|
|
# First click the Check USB Drives button to populate the list
|
|
$script:btnCheckUSBDrives.RaiseEvent(
|
|
[System.Windows.RoutedEventArgs]::new(
|
|
[System.Windows.Controls.Button]::ClickEvent
|
|
)
|
|
)
|
|
|
|
# Then select the drives that match the saved configuration
|
|
foreach ($item in $script:lstUSBDrives.Items) {
|
|
if ($configContent.USBDriveList.ContainsKey($item.Model) -and
|
|
$configContent.USBDriveList[$item.Model] -eq $item.SerialNumber) {
|
|
$item.IsSelected = $true
|
|
}
|
|
}
|
|
$script:lstUSBDrives.Items.Refresh()
|
|
|
|
# Update the Select All checkbox state
|
|
$allSelected = -not ($script:lstUSBDrives.Items | Where-Object { -not $_.IsSelected })
|
|
$script:chkSelectAllUSBDrives.IsChecked = $allSelected
|
|
}
|
|
}
|
|
}
|
|
catch {
|
|
[System.Windows.MessageBox]::Show("Error loading config file:`n$_","Error","OK","Error")
|
|
}
|
|
})
|
|
|
|
[void]$window.ShowDialog()
|