mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
feat: Add MaxUSBDrives parameter for parallel USB drive processing
- Introduced a new parameter `MaxUSBDrives` to control the maximum number of USB drives that can be built in parallel, with a default value of 5. - Updated UI to include a textbox for setting `MaxUSBDrives`. - Implemented validation to ensure the value is a non-negative integer. - Adjusted the deployment function to respect the `MaxUSBDrives` limit during USB drive creation.
This commit is contained in:
@@ -193,6 +193,9 @@ A hashtable containing USB drives from win32_diskdrive where:
|
|||||||
|
|
||||||
Example: @{ "SanDisk Ultra" = "1234567890"; "Kingston DataTraveler" = "0987654321" }
|
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
|
.PARAMETER UserAgent
|
||||||
User agent string to use when downloading files.
|
User agent string to use when downloading files.
|
||||||
|
|
||||||
@@ -344,6 +347,7 @@ param(
|
|||||||
[string]$ProductKey,
|
[string]$ProductKey,
|
||||||
[bool]$BuildUSBDrive,
|
[bool]$BuildUSBDrive,
|
||||||
[hashtable]$USBDriveList,
|
[hashtable]$USBDriveList,
|
||||||
|
[int]$MaxUSBDrives = 5,
|
||||||
[Parameter(Mandatory = $false)]
|
[Parameter(Mandatory = $false)]
|
||||||
[ValidateSet(10, 11, 2016, 2019, 2021, 2022, 2024, 2025)]
|
[ValidateSet(10, 11, 2016, 2019, 2021, 2022, 2024, 2025)]
|
||||||
[int]$WindowsRelease = 11,
|
[int]$WindowsRelease = 11,
|
||||||
@@ -3310,6 +3314,9 @@ Function New-DeploymentUSB {
|
|||||||
# 2. Partition and format USB drives in parallel
|
# 2. Partition and format USB drives in parallel
|
||||||
WriteLog "Starting parallel creation for $USBDrivesCount USB drive(s)."
|
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 {
|
$USBDrives | ForEach-Object -Parallel {
|
||||||
$USBDrive = $_
|
$USBDrive = $_
|
||||||
|
|
||||||
@@ -3391,7 +3398,7 @@ Function New-DeploymentUSB {
|
|||||||
Set-Volume -DriveLetter $DeployPartition.DriveLetter -NewFileSystemLabel "Deploy"
|
Set-Volume -DriveLetter $DeployPartition.DriveLetter -NewFileSystemLabel "Deploy"
|
||||||
WriteLog "Finished processing disk $DiskNumber"
|
WriteLog "Finished processing disk $DiskNumber"
|
||||||
|
|
||||||
} -ThrottleLimit 2
|
} -ThrottleLimit $resolvedUSBThrottle
|
||||||
|
|
||||||
# Dismount ISO after all parallel jobs are complete
|
# Dismount ISO after all parallel jobs are complete
|
||||||
WriteLog "Dismounting deployment ISO."
|
WriteLog "Dismounting deployment ISO."
|
||||||
|
|||||||
@@ -755,6 +755,12 @@
|
|||||||
<CheckBox x:Name="chkCopyUnattend" Content="Copy Unattend.xml" Margin="5" VerticalAlignment="Center" Tag="When set to $true, will copy the Unattend.xml file to the USB drive."/>
|
<CheckBox x:Name="chkCopyUnattend" Content="Copy Unattend.xml" Margin="5" VerticalAlignment="Center" Tag="When set to $true, will copy the Unattend.xml file to the USB drive."/>
|
||||||
<CheckBox x:Name="chkCopyPPKG" Content="Copy Provisioning Package" Margin="5" VerticalAlignment="Center" Tag="When set to $true, will copy the provisioning package to the USB drive."/>
|
<CheckBox x:Name="chkCopyPPKG" Content="Copy Provisioning Package" Margin="5" VerticalAlignment="Center" Tag="When set to $true, will copy the provisioning package to the USB drive."/>
|
||||||
|
|
||||||
|
<!-- Max USB Drives -->
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="5">
|
||||||
|
<TextBlock Text="Max USB Drives" VerticalAlignment="Center" ToolTip="Maximum number of USB drives to build at once. Enter 0 to process all discovered (or all selected) drives."/>
|
||||||
|
<TextBox x:Name="txtMaxUSBDrives" Width="50" Margin="10,0,0,0" Text="5" VerticalAlignment="Center" ToolTip="Maximum number of USB drives to build at once. Enter 0 to process all discovered (or all selected) drives."/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<!-- USB Drive Selection Section -->
|
<!-- USB Drive Selection Section -->
|
||||||
<Grid x:Name="usbDriveSelectionPanel" Margin="5,0,0,0">
|
<Grid x:Name="usbDriveSelectionPanel" Margin="5,0,0,0">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ function Get-UIConfig {
|
|||||||
USBDriveList = @{}
|
USBDriveList = @{}
|
||||||
Username = $State.Controls.txtUsername.Text
|
Username = $State.Controls.txtUsername.Text
|
||||||
Threads = [int]$State.Controls.txtThreads.Text
|
Threads = [int]$State.Controls.txtThreads.Text
|
||||||
|
MaxUSBDrives = [int]$State.Controls.txtMaxUSBDrives.Text
|
||||||
Verbose = $State.Controls.chkVerbose.IsChecked
|
Verbose = $State.Controls.chkVerbose.IsChecked
|
||||||
VMHostIPAddress = $State.Controls.txtVMHostIPAddress.Text
|
VMHostIPAddress = $State.Controls.txtVMHostIPAddress.Text
|
||||||
VMLocation = $State.Controls.txtVMLocation.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 'txtShareName' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'ShareName' -State $State
|
||||||
Set-UIValue -ControlName 'txtUsername' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'Username' -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 '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 'chkBuildUSBDriveEnable' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'BuildUSBDrive' -State $State
|
||||||
Set-UIValue -ControlName 'chkCompactOS' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'CompactOS' -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
|
Set-UIValue -ControlName 'chkUpdateADK' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'UpdateADK' -State $State
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ function Register-EventHandlers {
|
|||||||
$State.Controls.txtDiskSize,
|
$State.Controls.txtDiskSize,
|
||||||
$State.Controls.txtMemory,
|
$State.Controls.txtMemory,
|
||||||
$State.Controls.txtProcessors,
|
$State.Controls.txtProcessors,
|
||||||
$State.Controls.txtThreads
|
$State.Controls.txtThreads,
|
||||||
|
$State.Controls.txtMaxUSBDrives
|
||||||
)
|
)
|
||||||
|
|
||||||
# Attach the handlers to each relevant textbox
|
# 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
|
# Build Tab Event Handlers
|
||||||
$State.Controls.btnBrowseFFUDevPath.Add_Click({
|
$State.Controls.btnBrowseFFUDevPath.Add_Click({
|
||||||
param($eventSource, $routedEventArgs)
|
param($eventSource, $routedEventArgs)
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ function Initialize-UIControls {
|
|||||||
$State.Controls.txtShareName = $window.FindName('txtShareName')
|
$State.Controls.txtShareName = $window.FindName('txtShareName')
|
||||||
$State.Controls.txtUsername = $window.FindName('txtUsername')
|
$State.Controls.txtUsername = $window.FindName('txtUsername')
|
||||||
$State.Controls.txtThreads = $window.FindName('txtThreads')
|
$State.Controls.txtThreads = $window.FindName('txtThreads')
|
||||||
|
$State.Controls.txtMaxUSBDrives = $window.FindName('txtMaxUSBDrives')
|
||||||
$State.Controls.chkCompactOS = $window.FindName('chkCompactOS')
|
$State.Controls.chkCompactOS = $window.FindName('chkCompactOS')
|
||||||
$State.Controls.chkOptimize = $window.FindName('chkOptimize')
|
$State.Controls.chkOptimize = $window.FindName('chkOptimize')
|
||||||
$State.Controls.chkAllowVHDXCaching = $window.FindName('chkAllowVHDXCaching')
|
$State.Controls.chkAllowVHDXCaching = $window.FindName('chkAllowVHDXCaching')
|
||||||
@@ -227,6 +228,7 @@ function Initialize-UIDefaults {
|
|||||||
$State.Controls.txtShareName.Text = $State.Defaults.generalDefaults.ShareName
|
$State.Controls.txtShareName.Text = $State.Defaults.generalDefaults.ShareName
|
||||||
$State.Controls.txtUsername.Text = $State.Defaults.generalDefaults.Username
|
$State.Controls.txtUsername.Text = $State.Defaults.generalDefaults.Username
|
||||||
$State.Controls.txtThreads.Text = $State.Defaults.generalDefaults.Threads
|
$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.chkBuildUSBDriveEnable.IsChecked = $State.Defaults.generalDefaults.BuildUSBDriveEnable
|
||||||
$State.Controls.chkCompactOS.IsChecked = $State.Defaults.generalDefaults.CompactOS
|
$State.Controls.chkCompactOS.IsChecked = $State.Defaults.generalDefaults.CompactOS
|
||||||
$State.Controls.chkUpdateADK.IsChecked = $State.Defaults.generalDefaults.UpdateADK
|
$State.Controls.chkUpdateADK.IsChecked = $State.Defaults.generalDefaults.UpdateADK
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ function Get-GeneralDefaults {
|
|||||||
ShareName = "FFUCaptureShare"
|
ShareName = "FFUCaptureShare"
|
||||||
Username = "ffu_user"
|
Username = "ffu_user"
|
||||||
Threads = 5
|
Threads = 5
|
||||||
|
MaxUSBDrives = 5
|
||||||
BuildUSBDriveEnable = $false
|
BuildUSBDriveEnable = $false
|
||||||
CompactOS = $true
|
CompactOS = $true
|
||||||
Optimize = $true
|
Optimize = $true
|
||||||
|
|||||||
Reference in New Issue
Block a user