diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 0983a0c..bd41752 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -579,7 +579,7 @@ if (-not $AutopilotFolder) { $AutopilotFolder = "$FFUDevelopmentPath\Autopilot" if (-not $PEDriversFolder) { $PEDriversFolder = "$FFUDevelopmentPath\PEDrivers" } if (-not $VHDXCacheFolder) { $VHDXCacheFolder = "$FFUDevelopmentPath\VHDXCache" } if (-not $installationType) { $installationType = if ($WindowsSKU -like "Standard*" -or $WindowsSKU -like "Datacenter*") { 'Server' } else { 'Client' } } -if ($installationType -eq 'Server'){ +if ($installationType -eq 'Server') { #Map $WindowsRelease to $WindowsVersion for Windows Server switch ($WindowsRelease) { 2016 { $WindowsVersion = '1607' } @@ -1910,7 +1910,8 @@ function Get-WindowsESD { } elseif ($WindowsRelease -eq 11) { 'https://go.microsoft.com/fwlink/?LinkId=2156292' - } else { + } + else { throw "Downloading Windows $WindowsRelease is not supported. Please use the -ISOPath parameter to specify the path to the Windows $WindowsRelease ISO file." } @@ -2703,47 +2704,47 @@ function Get-ShortenedWindowsSKU { param ( [string]$WindowsSKU ) - $shortenedWindowsSKU = switch ($WindowsSKU) { - 'Core' { 'Home' } - 'Home' { 'Home' } - 'CoreN' { 'Home_N' } - 'Home N' { 'Home_N' } - 'CoreSingleLanguage' { 'Home_SL' } - 'Home Single Language' { 'Home_SL' } - 'Education' { 'Edu' } - 'EducationN' { 'Edu_N' } - 'Education N' { 'Edu_N' } - 'Professional' { 'Pro' } - 'Pro' { 'Pro' } - 'ProfessionalN' { 'Pro_N' } - 'Pro N' { 'Pro_N' } - 'ProfessionalEducation' { 'Pro_Edu' } - 'Pro Education' { 'Pro_Edu' } - 'ProfessionalEducationN' { 'Pro_Edu_N' } - 'Pro Education N' { 'Pro_Edu_N' } - 'ProfessionalWorkstation' { 'Pro_WKS' } - 'Pro for Workstations' { 'Pro_WKS' } - 'ProfessionalWorkstationN' { 'Pro_WKS_N' } - 'Pro N for Workstations' { 'Pro_WKS_N' } - 'Enterprise' { 'Ent' } - 'EnterpriseN' { 'Ent_N' } - 'Enterprise N' { 'Ent_N' } - 'Enterprise N LTSC' { 'Ent_N_LTSC' } - 'EnterpriseS' { 'Ent_LTSC' } - 'EnterpriseSN' { 'Ent_N_LTSC' } - 'Enterprise LTSC' { 'Ent_LTSC' } - 'Enterprise 2016 LTSB' { 'Ent_LTSC' } - 'Enterprise N 2016 LTSB' { 'Ent_N_LTSC' } - 'IoT Enterprise LTSC' { 'IoT_Ent_LTSC' } - 'IoTEnterpriseS' { 'IoT_Ent_LTSC' } - 'IoT Enterprise N LTSC' { 'IoT_Ent_N_LTSC' } - 'ServerStandard' { 'Srv_Std' } - 'Standard' { 'Srv_Std' } - 'ServerDatacenter' { 'Srv_Dtc' } - 'Datacenter' { 'Srv_Dtc' } - 'Standard (Desktop Experience)' { 'Srv_Std_DE' } - 'Datacenter (Desktop Experience)' { 'Srv_Dtc_DE' } - } + $shortenedWindowsSKU = switch ($WindowsSKU) { + 'Core' { 'Home' } + 'Home' { 'Home' } + 'CoreN' { 'Home_N' } + 'Home N' { 'Home_N' } + 'CoreSingleLanguage' { 'Home_SL' } + 'Home Single Language' { 'Home_SL' } + 'Education' { 'Edu' } + 'EducationN' { 'Edu_N' } + 'Education N' { 'Edu_N' } + 'Professional' { 'Pro' } + 'Pro' { 'Pro' } + 'ProfessionalN' { 'Pro_N' } + 'Pro N' { 'Pro_N' } + 'ProfessionalEducation' { 'Pro_Edu' } + 'Pro Education' { 'Pro_Edu' } + 'ProfessionalEducationN' { 'Pro_Edu_N' } + 'Pro Education N' { 'Pro_Edu_N' } + 'ProfessionalWorkstation' { 'Pro_WKS' } + 'Pro for Workstations' { 'Pro_WKS' } + 'ProfessionalWorkstationN' { 'Pro_WKS_N' } + 'Pro N for Workstations' { 'Pro_WKS_N' } + 'Enterprise' { 'Ent' } + 'EnterpriseN' { 'Ent_N' } + 'Enterprise N' { 'Ent_N' } + 'Enterprise N LTSC' { 'Ent_N_LTSC' } + 'EnterpriseS' { 'Ent_LTSC' } + 'EnterpriseSN' { 'Ent_N_LTSC' } + 'Enterprise LTSC' { 'Ent_LTSC' } + 'Enterprise 2016 LTSB' { 'Ent_LTSC' } + 'Enterprise N 2016 LTSB' { 'Ent_N_LTSC' } + 'IoT Enterprise LTSC' { 'IoT_Ent_LTSC' } + 'IoTEnterpriseS' { 'IoT_Ent_LTSC' } + 'IoT Enterprise N LTSC' { 'IoT_Ent_N_LTSC' } + 'ServerStandard' { 'Srv_Std' } + 'Standard' { 'Srv_Std' } + 'ServerDatacenter' { 'Srv_Dtc' } + 'Datacenter' { 'Srv_Dtc' } + 'Standard (Desktop Experience)' { 'Srv_Std_DE' } + 'Datacenter (Desktop Experience)' { 'Srv_Dtc_DE' } + } return $shortenedWindowsSKU } @@ -3956,53 +3957,14 @@ if ($driversJsonPath -and (Test-Path $driversJsonPath) -and ($InstallDrivers -or else { WriteLog "Found $($driversToProcess.Count) driver entries to process from $driversJsonPath." - $dellCatalogXmlPathForJob = $null - if ($driversToProcess | Where-Object { $_.Make -eq 'Dell' }) { - WriteLog "Dell drivers found in JSON, ensuring Dell Catalog XML is available..." - $dellDriversFolderScript = Join-Path -Path $DriversFolder -ChildPath "Dell" - $catalogBaseNameScript = if ($WindowsRelease -le 11) { "CatalogPC" } else { "Catalog" } - $dellCabFileScript = Join-Path -Path $dellDriversFolderScript -ChildPath "$($catalogBaseNameScript).cab" - $dellCatalogXmlPathForJob = Join-Path -Path $dellDriversFolderScript -ChildPath "$($catalogBaseNameScript).xml" - $catalogUrlScript = if ($WindowsRelease -le 11) { "http://downloads.dell.com/catalog/CatalogPC.cab" } else { "https://downloads.dell.com/catalog/Catalog.cab" } - - $downloadDellCatalogScript = $true - if (Test-Path -Path $dellCatalogXmlPathForJob -PathType Leaf) { - if (((Get-Date) - (Get-Item $dellCatalogXmlPathForJob).LastWriteTime).TotalDays -lt 7) { - WriteLog "Using existing Dell Catalog XML (less than 7 days old): $dellCatalogXmlPathForJob" - $downloadDellCatalogScript = $false - } - else { WriteLog "Existing Dell Catalog XML '$dellCatalogXmlPathForJob' is older than 7 days." } - } - else { WriteLog "Dell Catalog XML '$dellCatalogXmlPathForJob' not found." } - - if ($downloadDellCatalogScript) { - WriteLog "Dell Catalog XML '$dellCatalogXmlPathForJob' needs to be downloaded/updated." - try { - if (-not (Test-Path -Path $dellDriversFolderScript -PathType Container)) { New-Item -Path $dellDriversFolderScript -ItemType Directory -Force | Out-Null } - if (Test-Path $dellCabFileScript) { Remove-Item $dellCabFileScript -Force -ErrorAction SilentlyContinue } - if (Test-Path $dellCatalogXmlPathForJob) { Remove-Item $dellCatalogXmlPathForJob -Force -ErrorAction SilentlyContinue } - - Start-BitsTransferWithRetry -Source $catalogUrlScript -Destination $dellCabFileScript - Invoke-Process -FilePath "Expand.exe" -ArgumentList """$dellCabFileScript"" ""$dellCatalogXmlPathForJob""" | Out-Null - Remove-Item -Path $dellCabFileScript -Force -ErrorAction SilentlyContinue - WriteLog "Dell Catalog XML prepared at $dellCatalogXmlPathForJob" - } - catch { - WriteLog "Failed to prepare Dell Catalog XML: $($_.Exception.Message). Dell driver downloads may fail." - $dellCatalogXmlPathForJob = $null - } - } - } - $taskArguments = @{ - DriversFolder = $DriversFolder - WindowsRelease = $WindowsRelease - WindowsArch = $WindowsArch - WindowsVersion = $WindowsVersion - Headers = $Headers - UserAgent = $UserAgent - CompressToWim = $CompressDownloadedDriversToWim - DellCatalogXmlPath = $dellCatalogXmlPathForJob + DriversFolder = $DriversFolder + WindowsRelease = $WindowsRelease + WindowsArch = $WindowsArch + WindowsVersion = $WindowsVersion + Headers = $Headers + UserAgent = $UserAgent + CompressToWim = $CompressDownloadedDriversToWim } WriteLog "Starting parallel driver processing using Invoke-ParallelProcessing..." @@ -4318,7 +4280,7 @@ if ($InstallApps) { $Name = """Windows Malicious Software Removal Tool x64""" + " " + """Windows $WindowsRelease""" } # Handle LTSB/LTSC - elseif ($installationType -eq 'client' -and $isLTSC -eq $true){ + elseif ($installationType -eq 'client' -and $isLTSC -eq $true) { $Name = """Windows Malicious Software Removal Tool x64""" + " " + """LTSB""" } #Windows Server 2025 isn't listed as a product in the Microsoft Update Catalog, so we'll use the 2019 version @@ -4624,7 +4586,7 @@ try { if ($WindowsRelease -eq 2019) { $name = """Cumulative Update for .NET Framework 3.5, 4.7.2 and 4.8 for Windows 10 Version $WindowsVersion for $WindowsArch""" } - if ($WindowsRelease -eq 2021){ + if ($WindowsRelease -eq 2021) { $name = """Cumulative Update for .NET Framework 3.5, 4.8 and 4.8.1 for Windows 10 Version $WindowsVersion for $WindowsArch""" } @@ -4726,12 +4688,12 @@ try { } # Windows 10 LTSC 2016 (1607) and Windows Server 2016 - if($WindowsRelease -eq 2016){ + if ($WindowsRelease -eq 2016) { $name = "KB4589210 $windowsArch" } # Windows 10 LTSC 2019 (1809) and Windows Server 2019 - if($WindowsRelease -eq 2019){ + if ($WindowsRelease -eq 2019) { $name = "KB4589208 $windowsArch" } WriteLog "Searching for $name from Microsoft Update Catalog and saving to $MicrocodePath" @@ -4746,7 +4708,7 @@ try { WriteLog "Found $VHDXCacheFolder" $vhdxJsons = @(Get-ChildItem -File -Path $VHDXCacheFolder -Filter '*_config.json' | Sort-Object -Property CreationTime -Descending) WriteLog "Found $($vhdxJsons.Count) cached VHDX files" - if (Test-Path -Path $KBPath){ + if (Test-Path -Path $KBPath) { $downloadedKBs = @(Get-ChildItem -File -Path $KBPath -Recurse) } else { diff --git a/FFUDevelopment/BuildFFUVM_UI.ps1 b/FFUDevelopment/BuildFFUVM_UI.ps1 index 03ee336..04a2ab1 100644 --- a/FFUDevelopment/BuildFFUVM_UI.ps1 +++ b/FFUDevelopment/BuildFFUVM_UI.ps1 @@ -220,78 +220,17 @@ $window.Add_Loaded({ $localUserAgent = $coreStaticVars.UserAgent $compressDrivers = $script:uiState.Controls.chkCompressDriversToWIM.IsChecked - # --- Dell Catalog Handling (once, if Dell drivers are selected) --- - $dellCatalogXmlPath = $null # This will be the path passed to the background task - if ($selectedDrivers | Where-Object { $_.Make -eq 'Dell' }) { - $script:uiState.Controls.txtStatus.Text = "Checking Dell Catalog..." - WriteLog "Dell drivers selected. Preparing Dell catalog..." - - $dellDriversFolderUi = Join-Path -Path $localDriversFolder -ChildPath "Dell" - $catalogBaseName = if ($localWindowsRelease -le 11) { "CatalogPC" } else { "Catalog" } - $dellCabFileUi = Join-Path -Path $dellDriversFolderUi -ChildPath "$($catalogBaseName).cab" - # This $dellCatalogXmlPath is the one we ensure exists and is up-to-date for the Save-DellDriversTask - $dellCatalogXmlPath = Join-Path -Path $dellDriversFolderUi -ChildPath "$($catalogBaseName).xml" - $catalogUrl = if ($localWindowsRelease -le 11) { "http://downloads.dell.com/catalog/CatalogPC.cab" } else { "https://downloads.dell.com/catalog/Catalog.cab" } - - $downloadDellCatalog = $true - if (Test-Path -Path $dellCatalogXmlPath -PathType Leaf) { - if (((Get-Date) - (Get-Item $dellCatalogXmlPath).LastWriteTime).TotalDays -lt 7) { - WriteLog "Using existing Dell Catalog XML (less than 7 days old) for download task: $dellCatalogXmlPath" - $downloadDellCatalog = $false - $script:uiState.Controls.txtStatus.Text = "Dell Catalog ready." - } - else { - WriteLog "Existing Dell Catalog XML '$dellCatalogXmlPath' is older than 7 days." - } - } - else { - WriteLog "Dell Catalog XML '$dellCatalogXmlPath' not found." - } - - if ($downloadDellCatalog) { - WriteLog "Dell Catalog XML '$dellCatalogXmlPath' needs to be downloaded/updated for driver download task." - $script:uiState.Controls.txtStatus.Text = "Downloading Dell Catalog..." - try { - # Ensure Dell drivers folder exists - if (-not (Test-Path -Path $dellDriversFolderUi -PathType Container)) { - WriteLog "Creating Dell drivers folder: $dellDriversFolderUi" - New-Item -Path $dellDriversFolderUi -ItemType Directory -Force | Out-Null - } - - if (Test-Path $dellCabFileUi) { Remove-Item $dellCabFileUi -Force -ErrorAction SilentlyContinue } - if (Test-Path $dellCatalogXmlPath) { Remove-Item $dellCatalogXmlPath -Force -ErrorAction SilentlyContinue } - - # Using Start-BitsTransferWithRetry and Invoke-Process (available from FFUUI.Core.psm1) - Start-BitsTransferWithRetry -Source $catalogUrl -Destination $dellCabFileUi - WriteLog "Dell Catalog CAB downloaded to $dellCabFileUi" - Invoke-Process -FilePath "Expand.exe" -ArgumentList """$dellCabFileUi"" ""$dellCatalogXmlPath""" | Out-Null - WriteLog "Dell Catalog XML extracted to $dellCatalogXmlPath" - Remove-Item -Path $dellCabFileUi -Force -ErrorAction SilentlyContinue - WriteLog "Dell Catalog CAB file $dellCabFileUi deleted." - $script:uiState.Controls.txtStatus.Text = "Dell Catalog ready." - } - catch { - $errMsg = "Failed to download/extract Dell Catalog for driver download task: $($_.Exception.Message)" - WriteLog $errMsg; [System.Windows.MessageBox]::Show($errMsg, "Dell Catalog Error", "OK", "Error") - $dellCatalogXmlPath = $null # Ensure it's null if failed, Save-DellDriversTask will handle this - $script:uiState.Controls.txtStatus.Text = "Dell Catalog download failed. Dell drivers may not download." - } - } - } - # --- End Dell Catalog Handling --- - $script:uiState.Controls.txtStatus.Text = "Processing all selected drivers..." WriteLog "Processing all selected drivers: $($selectedDrivers.Model -join ', ')" $taskArguments = @{ - DriversFolder = $localDriversFolder - WindowsRelease = $localWindowsRelease - WindowsArch = $localWindowsArch - WindowsVersion = $localWindowsVersion - Headers = $localHeaders - UserAgent = $localUserAgent - CompressToWim = $compressDrivers - DellCatalogXmlPath = $dellCatalogXmlPath + DriversFolder = $localDriversFolder + WindowsRelease = $localWindowsRelease + WindowsArch = $localWindowsArch + WindowsVersion = $localWindowsVersion + Headers = $localHeaders + UserAgent = $localUserAgent + CompressToWim = $compressDrivers } Invoke-ParallelProcessing -ItemsToProcess $selectedDrivers ` diff --git a/FFUDevelopment/FFU.Common/FFU.Common.Parallel.psm1 b/FFUDevelopment/FFU.Common/FFU.Common.Parallel.psm1 index 304b9e6..2342a31 100644 --- a/FFUDevelopment/FFU.Common/FFU.Common.Parallel.psm1 +++ b/FFUDevelopment/FFU.Common/FFU.Common.Parallel.psm1 @@ -173,12 +173,10 @@ function Invoke-ParallelProcessing { -CompressToWim $localJobArgs['CompressToWim'] } 'Dell' { - # DellCatalogXmlPath might be null if catalog prep failed; Save-DellDriversTask should handle this. $taskResult = Save-DellDriversTask -DriverItemData $currentItem ` -DriversFolder $localJobArgs['DriversFolder'] ` -WindowsArch $localJobArgs['WindowsArch'] ` -WindowsRelease $localJobArgs['WindowsRelease'] ` - -DellCatalogXmlPath $localJobArgs['DellCatalogXmlPath'] ` -ProgressQueue $localProgressQueue ` -CompressToWim $localJobArgs['CompressToWim'] } diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Dell.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Dell.psm1 index 1d8b3bb..55c68d8 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Dell.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Dell.psm1 @@ -160,13 +160,10 @@ function Save-DellDriversTask { [string]$WindowsArch, [Parameter(Mandatory = $true)] [int]$WindowsRelease, - [Parameter(Mandatory = $true)] - [string]$DellCatalogXmlPath, # Path to the *existing* central XML catalog file [Parameter()] # Made optional [System.Collections.Concurrent.ConcurrentQueue[hashtable]]$ProgressQueue = $null, # Default to null [Parameter()] [bool]$CompressToWim = $false # New parameter for compression - # REMOVED: UI-related parameters, Catalog download/extract params ) $modelName = $DriverItemData.Model @@ -181,6 +178,42 @@ function Save-DellDriversTask { $modelPath = Join-Path -Path $makeDriversPath -ChildPath $modelName try { + # --- Dell Catalog Handling --- + $dellDriversFolder = Join-Path -Path $DriversFolder -ChildPath "Dell" + $catalogBaseName = if ($WindowsRelease -le 11) { "CatalogPC" } else { "Catalog" } + $dellCabFile = Join-Path -Path $dellDriversFolder -ChildPath "$($catalogBaseName).cab" + $dellCatalogXML = Join-Path -Path $dellDriversFolder -ChildPath "$($catalogBaseName).xml" + $catalogUrl = if ($WindowsRelease -le 11) { "http://downloads.dell.com/catalog/CatalogPC.cab" } else { "https://downloads.dell.com/catalog/Catalog.cab" } + + $downloadCatalog = $true + if (Test-Path -Path $dellCatalogXML -PathType Leaf) { + if (((Get-Date) - (Get-Item $dellCatalogXML).LastWriteTime).TotalDays -lt 7) { + WriteLog "Using existing Dell Catalog XML (less than 7 days old): $dellCatalogXML" + $downloadCatalog = $false + } + else { WriteLog "Existing Dell Catalog XML is older than 7 days: $dellCatalogXML" } + } + else { WriteLog "Dell Catalog XML not found: $dellCatalogXML" } + + if ($downloadCatalog) { + WriteLog "Downloading and extracting Dell Catalog for task..." + if (-not (Test-Path -Path $dellDriversFolder -PathType Container)) { + New-Item -Path $dellDriversFolder -ItemType Directory -Force | Out-Null + } + try { + $request = [System.Net.WebRequest]::Create($catalogUrl); $request.Method = 'HEAD'; $response = $request.GetResponse(); $response.Close() + } + catch { throw "Dell Catalog URL '$catalogUrl' not accessible: $($_.Exception.Message)" } + + if (Test-Path -Path $dellCabFile) { Remove-Item -Path $dellCabFile -Force -ErrorAction SilentlyContinue } + if (Test-Path -Path $dellCatalogXML) { Remove-Item -Path $dellCatalogXML -Force -ErrorAction SilentlyContinue } + + Start-BitsTransferWithRetry -Source $catalogUrl -Destination $dellCabFile + Invoke-Process -FilePath "Expand.exe" -ArgumentList """$dellCabFile"" ""$dellCatalogXML""" | Out-Null + Remove-Item -Path $dellCabFile -Force -ErrorAction SilentlyContinue + } + # --- End Dell Catalog Handling --- + # 1. Check if drivers already exist for this model (final destination) if (Test-Path -Path $modelPath -PathType Container) { $folderSize = (Get-ChildItem -Path $modelPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum @@ -195,19 +228,17 @@ function Save-DellDriversTask { } } - # 2. REMOVED: Download and Extract Catalog - This is now done centrally in the UI script - # 3. Parse the *EXISTING* XML and Find Drivers for *this specific model* $status = "Finding drivers..." if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelName -Status $status } # Check if the provided XML path exists - if (-not (Test-Path -Path $DellCatalogXmlPath -PathType Leaf)) { - throw "Dell Catalog XML file not found at specified path: $DellCatalogXmlPath" + if (-not (Test-Path -Path $dellCatalogXML -PathType Leaf)) { + throw "Dell Catalog XML file not found at specified path: $dellCatalogXML" } - WriteLog "Parsing existing Dell Catalog XML for model '$modelName' from: $DellCatalogXmlPath" - [xml]$xmlContent = Get-Content -Path $DellCatalogXmlPath + WriteLog "Parsing existing Dell Catalog XML for model '$modelName' from: $dellCatalogXML" + [xml]$xmlContent = Get-Content -Path $dellCatalogXML # Check if manifest and baseLocation exist before accessing if ($null -eq $xmlContent.manifest -or $null -eq $xmlContent.manifest.baseLocation) { throw "Invalid Dell Catalog XML format: Missing 'manifest' or 'baseLocation' element in '$DellCatalogXmlPath'." @@ -219,7 +250,7 @@ function Save-DellDriversTask { $softwareComponents = @($xmlContent.Manifest.SoftwareComponent | Where-Object { $_.ComponentType.value -eq "DRVR" }) $modelSpecificDriversFound = $false - WriteLog "Searching $($softwareComponents.Count) DRVR components in '$DellCatalogXmlPath' for model '$modelName'..." + WriteLog "Searching $($softwareComponents.Count) DRVR components in '$dellCatalogXML' for model '$modelName'..." foreach ($component in $softwareComponents) { # Check if SupportedSystems and Brand exist @@ -303,7 +334,7 @@ function Save-DellDriversTask { if (-not $modelSpecificDriversFound) { $status = "No drivers found for OS" - WriteLog "No drivers found for model '$modelName' matching Windows Release '$WindowsRelease' and Arch '$WindowsArch' in '$DellCatalogXmlPath'." + WriteLog "No drivers found for model '$modelName' matching Windows Release '$WindowsRelease' and Arch '$WindowsArch' in '$dellCatalogXML'." if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelName -Status $status } # Consider this success as the process completed, just no drivers to download return [PSCustomObject]@{ Model = $modelName; Status = $status; Success = $true }