diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 3588f17..2655518 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -193,6 +193,9 @@ A hashtable containing USB drives from win32_diskdrive where: Example: @{ "SanDisk Ultra" = "1234567890"; "Kingston DataTraveler" = "0987654321" } +.PARAMETER MaxUSBDrives +Maximum number of USB drives to build in parallel. Default is 5. Set to 0 to process all discovered drives (or all selected drives when USBDriveList or selection is used). Actual throttle will never exceed the number of drives discovered. + .PARAMETER UserAgent User agent string to use when downloading files. @@ -344,6 +347,7 @@ param( [string]$ProductKey, [bool]$BuildUSBDrive, [hashtable]$USBDriveList, + [int]$MaxUSBDrives = 5, [Parameter(Mandatory = $false)] [ValidateSet(10, 11, 2016, 2019, 2021, 2022, 2024, 2025)] [int]$WindowsRelease = 11, @@ -3310,6 +3314,9 @@ Function New-DeploymentUSB { # 2. Partition and format USB drives in parallel WriteLog "Starting parallel creation for $USBDrivesCount USB drive(s)." + $resolvedUSBThrottle = if ($MaxUSBDrives -gt 0) { [math]::Min($MaxUSBDrives, $USBDrivesCount) } else { $USBDrivesCount } + WriteLog "Using USB drive throttle limit: $resolvedUSBThrottle (MaxUSBDrives param: $MaxUSBDrives; Drives to process: $USBDrivesCount)" + $USBDrives | ForEach-Object -Parallel { $USBDrive = $_ @@ -3391,7 +3398,7 @@ Function New-DeploymentUSB { Set-Volume -DriveLetter $DeployPartition.DriveLetter -NewFileSystemLabel "Deploy" WriteLog "Finished processing disk $DiskNumber" - } -ThrottleLimit 2 + } -ThrottleLimit $resolvedUSBThrottle # Dismount ISO after all parallel jobs are complete WriteLog "Dismounting deployment ISO." diff --git a/FFUDevelopment/BuildFFUVM_UI.xaml b/FFUDevelopment/BuildFFUVM_UI.xaml index 817d2bc..5fb9c1e 100644 --- a/FFUDevelopment/BuildFFUVM_UI.xaml +++ b/FFUDevelopment/BuildFFUVM_UI.xaml @@ -755,6 +755,12 @@ + + + + + + diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 index 821b396..6216a36 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 @@ -93,6 +93,7 @@ function Get-UIConfig { USBDriveList = @{} Username = $State.Controls.txtUsername.Text Threads = [int]$State.Controls.txtThreads.Text + MaxUSBDrives = [int]$State.Controls.txtMaxUSBDrives.Text Verbose = $State.Controls.chkVerbose.IsChecked VMHostIPAddress = $State.Controls.txtVMHostIPAddress.Text VMLocation = $State.Controls.txtVMLocation.Text @@ -277,6 +278,7 @@ function Update-UIFromConfig { Set-UIValue -ControlName 'txtShareName' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'ShareName' -State $State Set-UIValue -ControlName 'txtUsername' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'Username' -State $State Set-UIValue -ControlName 'txtThreads' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'Threads' -State $State + Set-UIValue -ControlName 'txtMaxUSBDrives' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'MaxUSBDrives' -State $State Set-UIValue -ControlName 'chkBuildUSBDriveEnable' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'BuildUSBDrive' -State $State Set-UIValue -ControlName 'chkCompactOS' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'CompactOS' -State $State Set-UIValue -ControlName 'chkUpdateADK' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'UpdateADK' -State $State diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 index 93564bf..95f5d25 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 @@ -44,7 +44,8 @@ function Register-EventHandlers { $State.Controls.txtDiskSize, $State.Controls.txtMemory, $State.Controls.txtProcessors, - $State.Controls.txtThreads + $State.Controls.txtThreads, + $State.Controls.txtMaxUSBDrives ) # Attach the handlers to each relevant textbox @@ -72,6 +73,20 @@ function Register-EventHandlers { }) } + # Add specific validation for the Max USB Drives textbox to ensure it's an integer >=0 (allow 0 meaning all) + if ($null -ne $State.Controls.txtMaxUSBDrives) { + $State.Controls.txtMaxUSBDrives.Add_LostFocus({ + param($eventSource, $routedEventArgs) + $textBox = $eventSource + $currentValue = 0 + $isValidInteger = [int]::TryParse($textBox.Text, [ref]$currentValue) + if (-not $isValidInteger -or $currentValue -lt 0) { + $textBox.Text = '0' + WriteLog "Max USB Drives value was invalid or less than 0. Reset to 0 (process all)." + } + }) + } + # Build Tab Event Handlers $State.Controls.btnBrowseFFUDevPath.Add_Click({ param($eventSource, $routedEventArgs) diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 index a74e4a8..6352897 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 @@ -115,6 +115,7 @@ function Initialize-UIControls { $State.Controls.txtShareName = $window.FindName('txtShareName') $State.Controls.txtUsername = $window.FindName('txtUsername') $State.Controls.txtThreads = $window.FindName('txtThreads') + $State.Controls.txtMaxUSBDrives = $window.FindName('txtMaxUSBDrives') $State.Controls.chkCompactOS = $window.FindName('chkCompactOS') $State.Controls.chkOptimize = $window.FindName('chkOptimize') $State.Controls.chkAllowVHDXCaching = $window.FindName('chkAllowVHDXCaching') @@ -227,6 +228,7 @@ function Initialize-UIDefaults { $State.Controls.txtShareName.Text = $State.Defaults.generalDefaults.ShareName $State.Controls.txtUsername.Text = $State.Defaults.generalDefaults.Username $State.Controls.txtThreads.Text = $State.Defaults.generalDefaults.Threads + $State.Controls.txtMaxUSBDrives.Text = $State.Defaults.generalDefaults.MaxUSBDrives $State.Controls.chkBuildUSBDriveEnable.IsChecked = $State.Defaults.generalDefaults.BuildUSBDriveEnable $State.Controls.chkCompactOS.IsChecked = $State.Defaults.generalDefaults.CompactOS $State.Controls.chkUpdateADK.IsChecked = $State.Defaults.generalDefaults.UpdateADK diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 index 8a52943..f1efbb3 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 @@ -117,6 +117,7 @@ function Get-GeneralDefaults { ShareName = "FFUCaptureShare" Username = "ffu_user" Threads = 5 + MaxUSBDrives = 5 BuildUSBDriveEnable = $false CompactOS = $true Optimize = $true