Adds support for driver installation from WIM files

Updates the driver installation logic to prioritize searching for and installing drivers from .wim files located in the `Drivers` directory. If a single WIM is found, it is used automatically. If multiple WIMs are found, the user is prompted for a selection.

The script extracts the WIM to a temporary location before injecting the drivers. The previous method of installing from a folder is retained as a fallback if no WIM files are present. Error handling and cleanup for the WIM installation process are also included.
This commit is contained in:
rbalsleyMSFT
2025-06-24 16:13:02 -07:00
parent 4f5445a833
commit d2909ab21d
+90 -25
View File
@@ -409,17 +409,52 @@ else {
} }
#Find Drivers #Find Drivers
$Drivers = $USBDrive + "Drivers" $DriversPath = $USBDrive + "Drivers"
If (Test-Path -Path $Drivers) $WimToInstall = $null
$DriverFolderToInstall = $null
If (Test-Path -Path $DriversPath)
{ {
#Check if multiple driver folders found, if so, just select one folder to save time/space WriteLog "Searching for driver WIMs in $DriversPath"
$DriverFolders = Get-ChildItem -Path $Drivers -directory $WimFiles = Get-ChildItem -Path $DriversPath -Filter *.wim -Recurse
$DriverFoldersCount = $DriverFolders.count $WimFilesCount = $WimFiles.Count
if ($WimFilesCount -gt 0) {
WriteLog "Found $WimFilesCount driver WIM file(s)."
if ($WimFilesCount -eq 1) {
$WimToInstall = $WimFiles[0].FullName
WriteLog "Single driver WIM found, will install: $WimToInstall"
} else {
# Multiple WIMs found, prompt user
WriteLog "Multiple driver WIMs found. Prompting for selection."
$array = @()
for($i=0; $i -le $WimFilesCount -1; $i++){
$Properties = [ordered]@{Number = $i + 1; WimFile = $WimFiles[$i].FullName}
$array += New-Object PSObject -Property $Properties
}
$array | Format-Table -AutoSize -Property Number, WimFile
do {
try {
$var = $true
[int]$WimSelected = Read-Host 'Enter the number of the driver WIM to install'
$WimSelected = $WimSelected - 1
} catch {
Write-Host 'Input was not in correct format. Please enter a valid number.'
$var = $false
}
} until (($WimSelected -ge 0) -and ($WimSelected -le ($WimFilesCount -1)) -and $var)
$WimToInstall = $array[$WimSelected].WimFile
WriteLog "$WimToInstall was selected."
}
} else {
WriteLog "No driver WIMs found. Searching for driver folders."
# Fallback to folder logic
$DriverFolders = Get-ChildItem -Path $DriversPath -Directory
$DriverFoldersCount = $DriverFolders.Count
If ($DriverFoldersCount -gt 1) If ($DriverFoldersCount -gt 1)
{ {
WriteLog "Found $DriverFoldersCount driver folders" WriteLog "Found $DriverFoldersCount driver folders"
$array = @() $array = @()
for($i=0; $i -le $DriverFoldersCount -1; $i++){ for($i=0; $i -le $DriverFoldersCount -1; $i++){
$Properties = [ordered]@{Number = $i + 1; Drivers = $DriverFolders[$i].FullName} $Properties = [ordered]@{Number = $i + 1; Drivers = $DriverFolders[$i].FullName}
$array += New-Object PSObject -Property $Properties $array += New-Object PSObject -Property $Properties
@@ -430,26 +465,27 @@ If (Test-Path -Path $Drivers)
$var = $true $var = $true
[int]$DriversSelected = Read-Host 'Enter the set of drivers to install' [int]$DriversSelected = Read-Host 'Enter the set of drivers to install'
$DriversSelected = $DriversSelected - 1 $DriversSelected = $DriversSelected - 1
} } catch {
catch {
Write-Host 'Input was not in correct format. Please enter a valid driver folder number' Write-Host 'Input was not in correct format. Please enter a valid driver folder number'
$var = $false $var = $false
} }
} until (($DriversSelected -le $DriverFoldersCount -1) -and $var) } until (($DriversSelected -ge 0) -and ($DriversSelected -le ($DriverFoldersCount -1)) -and $var)
$Drivers = $array[$DriversSelected].Drivers $DriverFolderToInstall = $array[$DriversSelected].Drivers
WriteLog "$Drivers was selected" WriteLog "$DriverFolderToInstall was selected"
} }
elseif ($DriverFoldersCount -eq 1) { elseif ($DriverFoldersCount -eq 1) {
WriteLog "Found $DriverFoldersCount driver folder" WriteLog "Found $DriverFoldersCount driver folder"
$Drivers = $DriverFolders.FullName $DriverFolderToInstall = $DriverFolders[0].FullName
WriteLog "$Drivers will be installed" WriteLog "$DriverFolderToInstall will be installed"
} }
else { else {
Writelog 'No driver folders found' Writelog 'No driver WIMs or folders found in Drivers directory.'
} }
} }
} else {
WriteLog "Drivers folder not found at $DriversPath. Skipping driver installation."
}
#Partition drive #Partition drive
Writelog 'Clean Disk' Writelog 'Clean Disk'
try { try {
@@ -577,21 +613,50 @@ If ($computername){
} }
#Add Drivers #Add Drivers
#Some drivers can sometimes fail to copy and dism ends up with a non-zero error code. Invoke-process will throw and terminate in these instances. if ($null -ne $WimToInstall) {
If (Test-Path -Path $Drivers) WriteLog "Installing drivers from WIM: $WimToInstall"
{ $TempDriverDir = "W:\TempDrivers"
WriteLog 'Copying drivers' try {
WriteLog "Creating temporary directory for drivers at $TempDriverDir"
New-Item -Path $TempDriverDir -ItemType Directory -Force | Out-Null
WriteLog "Extracting WIM contents to $TempDriverDir"
Write-Warning 'Extracting Drivers from WIM - dism will pop a window with no progress. This can take a few minutes to complete. Please be patient.'
Invoke-Process dism.exe "/Apply-Image /ImageFile:""$WimToInstall"" /Index:1 /ApplyDir:""$TempDriverDir"""
WriteLog "WIM extraction successful."
WriteLog "Injecting drivers from $TempDriverDir"
Write-Warning 'Injecting Drivers from WIM - dism will pop a window with no progress. This can take a few minutes to complete. Please be patient.'
Invoke-Process dism.exe "/image:W:\ /Add-Driver /Driver:""$TempDriverDir"" /Recurse"
WriteLog "Driver injection from WIM succeeded."
} catch {
WriteLog "An error occurred during WIM driver installation: $_"
# Copy DISM log to USBDrive for debugging
invoke-process xcopy.exe "X:\Windows\logs\dism\dism.log $USBDrive /Y"
throw $_
} finally {
if (Test-Path -Path $TempDriverDir) {
WriteLog "Cleaning up temporary driver directory: $TempDriverDir"
Remove-Item -Path $TempDriverDir -Recurse -Force
WriteLog "Cleanup successful."
}
}
} elseif ($null -ne $DriverFolderToInstall) {
WriteLog "Injecting drivers from folder: $DriverFolderToInstall"
Write-Warning 'Copying Drivers - dism will pop a window with no progress. This can take a few minutes to complete. This is done so drivers are logged to the scriptlog.txt file. Please be patient.' Write-Warning 'Copying Drivers - dism will pop a window with no progress. This can take a few minutes to complete. This is done so drivers are logged to the scriptlog.txt file. Please be patient.'
Invoke-process dism.exe "/image:W:\ /Add-Driver /Driver:""$Drivers"" /Recurse" Invoke-Process dism.exe "/image:W:\ /Add-Driver /Driver:""$DriverFolderToInstall"" /Recurse"
WriteLog 'Copying drivers succeeded' WriteLog "Driver injection from folder succeeded."
} else {
WriteLog "No drivers to install."
} }
WriteLog "Setting Windows Boot Manager to be first in the display order." WriteLog "Setting Windows Boot Manager to be first in the firmware display order."
Invoke-Process bcdedit.exe "/set {fwbootmgr} displayorder {bootmgr} /addfirst" Invoke-Process bcdedit.exe "/set {fwbootmgr} displayorder {bootmgr} /addfirst"
WriteLog "Windows Boot Manager has been set to be first in the display order." WriteLog "Windows Boot Manager has been set to be first in the firmware display order."
WriteLog "Setting default Windows boot loader to be first in the display order." WriteLog "Setting Windows Boot Manager to be first in the default display order."
Invoke-Process bcdedit.exe "/set {bootmgr} displayorder {default} /addfirst" Invoke-Process bcdedit.exe "/set {bootmgr} displayorder {default} /addfirst"
WriteLog "The default Windows boot loader has been set to be first in the display order." WriteLog "Windows Boot Manager has been set to be first in the default display order."
#Copy DISM log to USBDrive #Copy DISM log to USBDrive
WriteLog "Copying dism log to $USBDrive" WriteLog "Copying dism log to $USBDrive"
invoke-process xcopy "X:\Windows\logs\dism\dism.log $USBDrive /Y" invoke-process xcopy "X:\Windows\logs\dism\dism.log $USBDrive /Y"