Feat: Auto-save selected drivers and refine script execution

Adds a feature to automatically save the selected drivers to `Drivers.json` upon download, preserving the user's selection for future use.

Improves script execution by:
- Ensuring the disk cleanup process completes before proceeding.
- Suppressing progress bars globally for a cleaner console output.
- Hiding non-critical warnings during driver installation.
- Removing an unused BITS transfer function and trailing whitespace.
This commit is contained in:
rbalsleyMSFT
2025-07-14 16:55:15 -07:00
parent 08c9d5a0e3
commit 21d5f74dd8
4 changed files with 118 additions and 49 deletions
@@ -11,7 +11,7 @@ Get-ChildItem -Path $rootKey | ForEach-Object {
} }
# Run the disk cleanup tool with the specified flags # Run the disk cleanup tool with the specified flags
Start-Process -FilePath "cleanmgr.exe" -ArgumentList "/sagerun:0" Start-Process -FilePath "cleanmgr.exe" -ArgumentList "/sagerun:0" -Wait
# Remove the StateFlags0000 registry values that were added # Remove the StateFlags0000 registry values that were added
Get-ChildItem -Path $rootKey | ForEach-Object { Get-ChildItem -Path $rootKey | ForEach-Object {
+49 -48
View File
@@ -403,6 +403,7 @@ param(
[string]$orchestrationPath, [string]$orchestrationPath,
[bool]$UpdateADK = $true [bool]$UpdateADK = $true
) )
$ProgressPreference = 'SilentlyContinue'
$version = '2505.1' $version = '2505.1'
# Remove any existing modules to avoid conflicts # Remove any existing modules to avoid conflicts
@@ -704,40 +705,40 @@ function Test-Url {
} }
# Function to download a file using BITS with retry and error handling # Function to download a file using BITS with retry and error handling
function Start-BitsTransferWithRetry { # function Start-BitsTransferWithRetry {
param ( # param (
[Parameter(Mandatory = $true)] # [Parameter(Mandatory = $true)]
[string]$Source, # [string]$Source,
[Parameter(Mandatory = $true)] # [Parameter(Mandatory = $true)]
[string]$Destination, # [string]$Destination,
[int]$Retries = 3 # [int]$Retries = 3
) # )
$attempt = 0 # $attempt = 0
$lastError = $null # $lastError = $null
while ($attempt -lt $Retries) { # while ($attempt -lt $Retries) {
try { # try {
$OriginalVerbosePreference = $VerbosePreference # $OriginalVerbosePreference = $VerbosePreference
$VerbosePreference = 'SilentlyContinue' # $VerbosePreference = 'SilentlyContinue'
$ProgressPreference = 'SilentlyContinue' # # $ProgressPreference = 'SilentlyContinue'
Start-BitsTransfer -Source $Source -Destination $Destination -ErrorAction Stop # Start-BitsTransfer -Source $Source -Destination $Destination -ErrorAction Stop
$ProgressPreference = 'Continue' # # $ProgressPreference = 'Continue'
$VerbosePreference = $OriginalVerbosePreference # $VerbosePreference = $OriginalVerbosePreference
return # return
} # }
catch { # catch {
# Capture the error that occurred during the failed download attempt # # Capture the error that occurred during the failed download attempt
$lastError = $_ # $lastError = $_
$attempt++ # $attempt++
WriteLog "Attempt $attempt of $Retries failed to download $Source with error: $($lastError.Exception.Message). Retrying..." # WriteLog "Attempt $attempt of $Retries failed to download $Source with error: $($lastError.Exception.Message). Retrying..."
Start-Sleep -Seconds 5 # Start-Sleep -Seconds 5
} # }
} # }
WriteLog "Failed to download $Source after $Retries attempts. Error: $($lastError.Exception.Message)" # WriteLog "Failed to download $Source after $Retries attempts. Error: $($lastError.Exception.Message)"
throw $lastError # throw $lastError
} # }
function Get-MicrosoftDrivers { function Get-MicrosoftDrivers {
param ( param (
@@ -925,9 +926,9 @@ function Get-MicrosoftDrivers {
elseif ($fileExtension -eq ".zip") { elseif ($fileExtension -eq ".zip") {
# Extract the ZIP file # Extract the ZIP file
WriteLog "Extracting ZIP file to $modelPath" WriteLog "Extracting ZIP file to $modelPath"
$ProgressPreference = 'SilentlyContinue' # $ProgressPreference = 'SilentlyContinue'
Expand-Archive -Path $filePath -DestinationPath $modelPath -Force Expand-Archive -Path $filePath -DestinationPath $modelPath -Force
$ProgressPreference = 'Continue' # $ProgressPreference = 'Continue'
WriteLog "Extraction complete" WriteLog "Extraction complete"
} }
else { else {
@@ -1946,7 +1947,7 @@ function Get-WindowsESD {
#Download if ESD file doesn't already exist #Download if ESD file doesn't already exist
If (-not (Test-Path $esdFilePath)) { If (-not (Test-Path $esdFilePath)) {
#Required to fix slow downloads #Required to fix slow downloads
$ProgressPreference = 'SilentlyContinue' # $ProgressPreference = 'SilentlyContinue'
WriteLog "Downloading $($file.filePath) to $esdFIlePath" WriteLog "Downloading $($file.filePath) to $esdFIlePath"
$OriginalVerbosePreference = $VerbosePreference $OriginalVerbosePreference = $VerbosePreference
$VerbosePreference = 'SilentlyContinue' $VerbosePreference = 'SilentlyContinue'
@@ -1954,7 +1955,7 @@ function Get-WindowsESD {
$VerbosePreference = $OriginalVerbosePreference $VerbosePreference = $OriginalVerbosePreference
WriteLog "Download succeeded" WriteLog "Download succeeded"
#Set back to show progress #Set back to show progress
$ProgressPreference = 'Continue' # $ProgressPreference = 'Continue'
WriteLog "Cleanup cab and xml file" WriteLog "Cleanup cab and xml file"
Remove-Item -Path $cabFilePath -Force Remove-Item -Path $cabFilePath -Force
Remove-Item -Path $xmlFilePath -Force Remove-Item -Path $xmlFilePath -Force
@@ -2279,11 +2280,11 @@ function New-ScratchVhdx {
WriteLog "Creating new Scratch VHDX..." WriteLog "Creating new Scratch VHDX..."
$newVHDX = New-VHD -Path $VhdxPath -SizeBytes $disksize -LogicalSectorSizeBytes $LogicalSectorSizeBytes -Dynamic:($Dynamic.IsPresent) $newVHDX = New-VHD -Path $VhdxPath -SizeBytes $disksize -LogicalSectorSizeBytes $LogicalSectorSizeBytes -Dynamic:($Dynamic.IsPresent)
$toReturn = $newVHDX | Mount-VHD -Passthru | Initialize-Disk -PassThru -PartitionStyle GPT $toReturn = $newVHDX | Mount-VHD -Passthru | Initialize-Disk -PassThru -PartitionStyle GPT
#Remove auto-created partition so we can create the correct partition layout #Remove auto-created partition so we can create the correct partition layout
remove-partition $toreturn.DiskNumber -PartitionNumber 1 -Confirm:$False remove-partition $toreturn.DiskNumber -PartitionNumber 1 -Confirm:$False
Writelog "Done." Writelog "Done."
return $toReturn return $toReturn
@@ -2298,8 +2299,8 @@ function New-SystemPartition {
WriteLog "Creating System partition..." WriteLog "Creating System partition..."
$sysPartition = $VhdxDisk | New-Partition -DriveLetter 'S' -Size $SystemPartitionSize -GptType "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}" -IsHidden $sysPartition = $VhdxDisk | New-Partition -DriveLetter 'S' -Size $SystemPartitionSize -GptType "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}" -IsHidden
$sysPartition | Format-Volume -FileSystem FAT32 -Force -NewFileSystemLabel "System" $sysPartition | Format-Volume -FileSystem FAT32 -Force -NewFileSystemLabel "System"
WriteLog 'Done.' WriteLog 'Done.'
return $sysPartition.DriveLetter return $sysPartition.DriveLetter
@@ -2334,13 +2335,13 @@ function New-OSPartition {
WriteLog "Creating OS partition..." WriteLog "Creating OS partition..."
if ($OSPartitionSize -gt 0) { if ($OSPartitionSize -gt 0) {
$osPartition = $vhdxDisk | New-Partition -DriveLetter 'W' -Size $OSPartitionSize -GptType "{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}" $osPartition = $vhdxDisk | New-Partition -DriveLetter 'W' -Size $OSPartitionSize -GptType "{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}"
} }
else { else {
$osPartition = $vhdxDisk | New-Partition -DriveLetter 'W' -UseMaximumSize -GptType "{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}" $osPartition = $vhdxDisk | New-Partition -DriveLetter 'W' -UseMaximumSize -GptType "{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}"
} }
$osPartition | Format-Volume -FileSystem NTFS -Confirm:$false -Force -NewFileSystemLabel "Windows" $osPartition | Format-Volume -FileSystem NTFS -Confirm:$false -Force -NewFileSystemLabel "Windows"
WriteLog 'Done' WriteLog 'Done'
Writelog "OS partition at drive $($osPartition.DriveLetter):" Writelog "OS partition at drive $($osPartition.DriveLetter):"
@@ -2404,7 +2405,7 @@ function New-RecoveryPartition {
} }
$recoveryPartition = $VhdxDisk | New-Partition -DriveLetter 'R' -UseMaximumSize -GptType "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}" ` $recoveryPartition = $VhdxDisk | New-Partition -DriveLetter 'R' -UseMaximumSize -GptType "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}" `
| Format-Volume -FileSystem NTFS -Confirm:$false -Force -NewFileSystemLabel 'Recovery' | Format-Volume -FileSystem NTFS -Confirm:$false -Force -NewFileSystemLabel 'Recovery'
WriteLog "Done. Recovery partition at drive $($recoveryPartition.DriveLetter):" WriteLog "Done. Recovery partition at drive $($recoveryPartition.DriveLetter):"
} }
@@ -2895,7 +2896,7 @@ function New-FFU {
WriteLog 'Mounting complete' WriteLog 'Mounting complete'
WriteLog 'Adding drivers - This will take a few minutes, please be patient' WriteLog 'Adding drivers - This will take a few minutes, please be patient'
try { try {
Add-WindowsDriver -Path "$FFUDevelopmentPath\Mount" -Driver "$DriversFolder" -Recurse -ErrorAction SilentlyContinue | Out-null Add-WindowsDriver -Path "$FFUDevelopmentPath\Mount" -Driver "$DriversFolder" -Recurse -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-null
} }
catch { catch {
WriteLog 'Some drivers failed to be added to the FFU. This can be expected. Continuing.' WriteLog 'Some drivers failed to be added to the FFU. This can be expected. Continuing.'
@@ -3317,8 +3318,8 @@ Function New-DeploymentUSB {
# Get-Disk $DiskNumber | Get-Partition | Remove-Partition # Get-Disk $DiskNumber | Get-Partition | Remove-Partition
$BootPartition = $Disk | New-Partition -Size 2GB -IsActive -AssignDriveLetter $BootPartition = $Disk | New-Partition -Size 2GB -IsActive -AssignDriveLetter
$DeployPartition = $Disk | New-Partition -UseMaximumSize -AssignDriveLetter $DeployPartition = $Disk | New-Partition -UseMaximumSize -AssignDriveLetter
Format-Volume -Partition $BootPartition -FileSystem FAT32 -NewFileSystemLabel "TempBoot" -Confirm:$false Format-Volume -Partition $BootPartition -FileSystem FAT32 -NewFileSystemLabel "TempBoot" -Confirm:$false
Format-Volume -Partition $DeployPartition -FileSystem NTFS -NewFileSystemLabel "TempDeploy" -Confirm:$false Format-Volume -Partition $DeployPartition -FileSystem NTFS -NewFileSystemLabel "TempDeploy" -Confirm:$false
} }
WriteLog 'Partitioning USB Drive' WriteLog 'Partitioning USB Drive'
@@ -5036,9 +5037,9 @@ try {
WriteLog 'Caching VHDX file' WriteLog 'Caching VHDX file'
WriteLog 'Defragmenting Windows partition...' WriteLog 'Defragmenting Windows partition...'
Optimize-Volume -DriveLetter $osPartition.DriveLetter -Defrag -NormalPriority Optimize-Volume -DriveLetter $osPartition.DriveLetter -Defrag -NormalPriority
WriteLog 'Performing slab consolidation on Windows partition...' WriteLog 'Performing slab consolidation on Windows partition...'
Optimize-Volume -DriveLetter $osPartition.DriveLetter -SlabConsolidate -NormalPriority Optimize-Volume -DriveLetter $osPartition.DriveLetter -SlabConsolidate -NormalPriority
WriteLog 'Dismounting VHDX' WriteLog 'Dismounting VHDX'
Dismount-ScratchVhdx -VhdxPath $VHDXPath Dismount-ScratchVhdx -VhdxPath $VHDXPath
@@ -257,4 +257,7 @@ function Set-Progress {
WriteLog "[PROGRESS] $Percentage | $Message" WriteLog "[PROGRESS] $Percentage | $Message"
} }
# Suppress the default progress bar for a cleaner console output for any script importing this module.
# $ProgressPreference = 'SilentlyContinue'
Export-ModuleMember -Function * Export-ModuleMember -Function *
@@ -695,6 +695,71 @@ function Invoke-DownloadSelectedDrivers {
} }
} }
# Automatically save the selected drivers to the specified Drivers.json path
$driversJsonPath = $State.Controls.txtDriversJsonPath.Text
if (-not [string]::IsNullOrWhiteSpace($driversJsonPath) -and $selectedDrivers.Count -gt 0) {
WriteLog "Attempting to automatically save selected drivers list to $driversJsonPath"
try {
$outputJson = @{} # Use a Hashtable for the desired structure
$selectedDrivers | Group-Object -Property Make | ForEach-Object {
$makeName = $_.Name
$modelsForThisMake = @() # Initialize an array to hold model objects
foreach ($driverItem in $_.Group) {
$modelObject = $null
switch ($makeName) {
'Microsoft' {
$modelObject = @{
Name = $driverItem.Model # Model is the display name
Link = $driverItem.Link
}
}
'Dell' {
$modelObject = @{
Name = $driverItem.Model # Model is the display name
}
}
'HP' {
$modelObject = @{
Name = $driverItem.Model
}
}
'Lenovo' {
$modelObject = @{
Name = $driverItem.Model
ProductName = $driverItem.ProductName
MachineType = $driverItem.MachineType
}
}
default {
WriteLog "Auto-Save Drivers.json: Unrecognized Make '$makeName' for driver '$($driverItem.Model)'. Skipping."
}
}
if ($null -ne $modelObject) {
$modelsForThisMake += $modelObject
}
}
# Add the models array to the make-specific object
$outputJson[$makeName] = @{ Models = $modelsForThisMake }
}
# Ensure directory exists
$parentDir = Split-Path -Path $driversJsonPath -Parent
if (-not (Test-Path -Path $parentDir -PathType Container)) {
WriteLog "Creating directory for Drivers.json: $parentDir"
New-Item -Path $parentDir -ItemType Directory -Force | Out-Null
}
$outputJson | ConvertTo-Json -Depth 5 | Set-Content -Path $driversJsonPath -Encoding UTF8
WriteLog "Successfully auto-saved selected drivers to $driversJsonPath"
}
catch {
WriteLog "Failed to automatically save selected drivers to $driversJsonPath. Error: $($_.Exception.Message)"
# This is a best-effort operation, so we only log the error and don't bother the user with a popup.
}
}
$State.Controls.pbOverallProgress.Visibility = 'Collapsed' $State.Controls.pbOverallProgress.Visibility = 'Collapsed'
$Button.IsEnabled = $true $Button.IsEnabled = $true
if ($overallSuccess) { if ($overallSuccess) {