diff --git a/Get-AmdGraphicsDrivers.ps1 b/Get-AmdGraphicsDrivers.ps1 new file mode 100644 index 0000000..b124980 --- /dev/null +++ b/Get-AmdGraphicsDrivers.ps1 @@ -0,0 +1,34 @@ +#Requires -Version 7.0 +<# + .SYNOPSIS + Fetches the latest AMD Radeon GPU display drivers (consumer + Radeon Pro) from the Microsoft Update Catalog. + + .DESCRIPTION + Thin shim over catalogscrape\CatalogScrape.psm1, driven by catalogscrape\amd-gfx.psd1. Drivers come from + the catalog (single-source): consumer Radeon RX and workstation Radeon Pro both publish "Advanced Micro + Devices, Inc. - Display" packages, listed per family because of AMD's current/legacy branch split. + Selection is highest-version-first (catalog date as tiebreak). + + .NOTES + SCOPE: POST-BOOT CONVENIENCE drivers only. A GPU cannot serve iSCSI/PXE boot, so nothing here is + boot-critical — it only provides accelerated display after the OS is running. A bare INF install + (offline DISM or live pnputil) delivers a fully accelerated driver incl. the OpenGL/Vulkan/OpenCL/D3D + runtimes; the AMD Software (Adrenalin) app is not included and is out of scope. For Radeon Pro cards the + catalog serves the base WHQL display driver, NOT the ISV-certified PRO Edition (out of scope). + + .EXAMPLE + .\Get-AmdGraphicsDrivers.ps1 + .EXAMPLE + .\Get-AmdGraphicsDrivers.ps1 -Install +#> +[CmdletBinding()] +param( + [switch]$Install, + [string]$DownloadPath = 'C:\Temp', + [ValidateSet('x64', 'arm64', 'all')][string]$Architecture = 'x64' +) + +$csDir = Join-Path $PSScriptRoot 'catalogscrape' +Import-Module (Join-Path $csDir 'CatalogScrape.psm1') -Force +$config = Import-PowerShellDataFile (Join-Path $csDir 'amd-gfx.psd1') +Invoke-DriverScrape -Config $config -Install:$Install -DownloadPath $DownloadPath -Architecture $Architecture diff --git a/Get-IntelGraphicsDrivers.ps1 b/Get-IntelGraphicsDrivers.ps1 new file mode 100644 index 0000000..a240903 --- /dev/null +++ b/Get-IntelGraphicsDrivers.ps1 @@ -0,0 +1,33 @@ +#Requires -Version 7.0 +<# + .SYNOPSIS + Fetches the latest Intel GPU (Arc / Iris Xe / UHD) display drivers from the Microsoft Update Catalog. + + .DESCRIPTION + Thin shim over catalogscrape\CatalogScrape.psm1, driven by catalogscrape\intel-gfx.psd1. Intel ships a + unified DCH display driver, so a single "Intel Corporation - Display" package covers Arc A/B-series, + Iris Xe, and recent integrated graphics. Selection is highest-version-first (catalog date as tiebreak). + + .NOTES + SCOPE: POST-BOOT CONVENIENCE drivers only. A GPU cannot serve iSCSI/PXE boot, so nothing here is + boot-critical — it only provides accelerated display after the OS is running. A bare INF install + (offline DISM or live pnputil) delivers a fully accelerated driver incl. the OpenGL/Vulkan/OpenCL/D3D + runtimes; the optional Microsoft Store control-panel app (Intel Graphics Software) is not included and + is out of scope. + + .EXAMPLE + .\Get-IntelGraphicsDrivers.ps1 + .EXAMPLE + .\Get-IntelGraphicsDrivers.ps1 -Install +#> +[CmdletBinding()] +param( + [switch]$Install, + [string]$DownloadPath = 'C:\Temp', + [ValidateSet('x64', 'arm64', 'all')][string]$Architecture = 'x64' +) + +$csDir = Join-Path $PSScriptRoot 'catalogscrape' +Import-Module (Join-Path $csDir 'CatalogScrape.psm1') -Force +$config = Import-PowerShellDataFile (Join-Path $csDir 'intel-gfx.psd1') +Invoke-DriverScrape -Config $config -Install:$Install -DownloadPath $DownloadPath -Architecture $Architecture diff --git a/Get-NvidiaGraphicsDrivers.ps1 b/Get-NvidiaGraphicsDrivers.ps1 new file mode 100644 index 0000000..0789282 --- /dev/null +++ b/Get-NvidiaGraphicsDrivers.ps1 @@ -0,0 +1,34 @@ +#Requires -Version 7.0 +<# + .SYNOPSIS + Fetches the latest NVIDIA GPU display drivers (GeForce + RTX/Quadro) from the Microsoft Update Catalog. + + .DESCRIPTION + Thin shim over catalogscrape\CatalogScrape.psm1, driven by catalogscrape\nvidia-gfx.psd1. Drivers come + from the catalog (single-source), NOT nvidia.com: HWID targeting separates the unified consumer GeForce + package from the professional RTX/Quadro production-branch package. Selection is highest-version-first. + + .NOTES + SCOPE: POST-BOOT CONVENIENCE drivers only. A GPU cannot serve iSCSI/PXE boot, so nothing here is + boot-critical — it only provides accelerated display after the OS is running. A bare INF install + (offline DISM or live pnputil) delivers a fully accelerated driver incl. the OpenGL/Vulkan/OpenCL/D3D + ICDs and the CUDA/NVENC runtime; the NVIDIA App / Control Panel (Microsoft Store) and the full CUDA + toolkit are not included and are out of scope. Catalog gives newest-WHQL, not day-0 Game Ready, with no + GRD-vs-Studio choice; Data Center (Tesla) and vGPU/GRID drivers are out of scope. + + .EXAMPLE + .\Get-NvidiaGraphicsDrivers.ps1 + .EXAMPLE + .\Get-NvidiaGraphicsDrivers.ps1 -Install +#> +[CmdletBinding()] +param( + [switch]$Install, + [string]$DownloadPath = 'C:\Temp', + [ValidateSet('x64', 'arm64', 'all')][string]$Architecture = 'x64' +) + +$csDir = Join-Path $PSScriptRoot 'catalogscrape' +Import-Module (Join-Path $csDir 'CatalogScrape.psm1') -Force +$config = Import-PowerShellDataFile (Join-Path $csDir 'nvidia-gfx.psd1') +Invoke-DriverScrape -Config $config -Install:$Install -DownloadPath $DownloadPath -Architecture $Architecture diff --git a/README.md b/README.md index 2ed8f48..996cb60 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,20 @@ BitLocker auto-encryption, injects LabConfig hardware-check bypasses and `Bypass and drops an `unattend.xml` (local `lan` admin account with autologon) plus a `SetupComplete.cmd` that disables NIC power management. -- `-Drivers` runs every `Get-*Drivers.ps1` scraper in parallel and injects the - results with `DISM /Add-Driver`. +- `-Drivers` runs every NIC/Wi-Fi `Get-*Drivers.ps1` scraper in parallel (the + `Get-*GraphicsDrivers.ps1` shims are excluded — see `-GraphicsDrivers`) and injects + the results with `DISM /Add-Driver`. +- `-GraphicsDrivers Intel|AMD|NVIDIA|All` additionally injects GPU display drivers + (also catalog-sourced) into the same image. GPU CABs are large (~0.6–1.2 GB each), + so it is opt-in and separate from `-Drivers`; `All` injects the ~3–5 GB union of all + three vendors, so prefer a single vendor matching the target machine. GPU drivers are + post-boot-only (a GPU never serves iSCSI boot), so they get plain `DISM /Add-Driver` + with **no** boot-start promotion. A bare INF install yields a fully accelerated driver + (incl. the OpenGL/Vulkan/OpenCL/D3D and CUDA/NVENC runtimes); the vendor control-panel + apps (NVIDIA App, AMD Adrenalin, Intel Graphics Software — all Microsoft Store) are not + installed, and Radeon Pro cards get the base WHQL driver, not the ISV-certified PRO + Edition. x64 only (discrete GPUs have no ARM64 Windows driver; Qualcomm Adreno is not + on the catalog). The same shims run standalone on a live system (`-Install` → `pnputil`). - `-Updates` runs `Get-Win11CumulativeUpdates.ps1` and injects the latest cumulative update (with checkpoint prerequisites) via folder-based `DISM /Add-Package`. @@ -96,6 +108,9 @@ Driver/update scrapers (Microsoft Update Catalog): | `Get-IntelWiFiDrivers.ps1` | Intel Wi-Fi 6/6E/7 (post-boot convenience) | | `Get-MediatekWiFiDrivers.ps1` | MediaTek MT79xx Wi-Fi (post-boot convenience) | | `Get-QualcommWiFiDrivers.ps1` | Qualcomm WCN/FastConnect Wi-Fi (post-boot convenience) | +| `Get-IntelGraphicsDrivers.ps1` | Intel Arc / Iris Xe / UHD GPU (post-boot convenience) | +| `Get-NvidiaGraphicsDrivers.ps1` | NVIDIA GeForce + RTX/Quadro GPU (post-boot convenience) | +| `Get-AmdGraphicsDrivers.ps1` | AMD Radeon RX + Radeon Pro GPU (post-boot convenience) | | `Get-Win11CumulativeUpdates.ps1` | Latest monthly CU + checkpoint chain + SSU per Windows version | **Status:** the `0x7B INACCESSIBLE_BOOT_DEVICE` failure (DISM apply + service-key diff --git a/build_win11pxe.ps1 b/build_win11pxe.ps1 index a887306..9ddcf4d 100644 --- a/build_win11pxe.ps1 +++ b/build_win11pxe.ps1 @@ -11,6 +11,9 @@ to allow the OS to boot from an iSCSI target (iBFT). .EXAMPLE .\build_win11pxe.ps1 -IsoPath .\Win11_25H2_English_x64.iso -OutPath .\win11_netboot.vhdx -ImageIndex 6 + +.EXAMPLE +.\build_win11pxe.ps1 -IsoPath .\Win11_25H2_English_x64.iso -Drivers -GraphicsDrivers NVIDIA -Updates #> param( @@ -32,6 +35,15 @@ param( [Parameter(Mandatory = $false)] [switch]$Updates, + # Inject GPU display drivers (post-boot only; a GPU never serves iSCSI boot, so unlike the NIC + # scrapers these get NO boot-start promotion — see the $nicDriverDefs note). Catalog-sourced like + # every other scraper. GPU CABs are large (~0.6-1.2 GB each), so this is opt-in and separate from + # -Drivers. 'All' runs Intel+AMD+NVIDIA (heavier, ~3-5 GB union); pick a single vendor to inject only + # the target machine's GPU driver. x64 only — discrete GPUs have no ARM64 Windows driver. + [Parameter(Mandatory = $false)] + [ValidateSet('Intel', 'AMD', 'NVIDIA', 'All')] + [string]$GraphicsDrivers, + # Adapter GUID(s) of the boot NIC, for the offline DISM /Add-NetAdapter step # that actually makes Windows able to boot over iSCSI (see notes below). # Obtain on a live machine / WinPE where that NIC is present: @@ -179,13 +191,39 @@ try { throw "DISM /Apply-Image failed with exit code $LASTEXITCODE. Check log: $dismLogPath" } - if ($Drivers) { + if ($Drivers -or $GraphicsDrivers) { Write-Host ">>> Executing Driver Scrapers (parallel)..." -ForegroundColor Cyan $driverTempPath = Join-Path $env:TEMP "Win11Drivers_$(Get-Random)" # Pre-create the root so the post-run enumeration never hits a missing path # when every scraper fails. New-Item -ItemType Directory -Path $driverTempPath -Force | Out-Null - $driverScripts = Get-ChildItem -Path $PSScriptRoot -Filter "Get-*Drivers.ps1" + + # NIC/Wi-Fi scrapers (-Drivers). Graphics shims are named Get-*GraphicsDrivers.ps1 and are + # EXCLUDED here so they run only on explicit -GraphicsDrivers opt-in (their CABs are large). + $driverScripts = @() + if ($Drivers) { + $driverScripts += Get-ChildItem -Path $PSScriptRoot -Filter "Get-*Drivers.ps1" | + Where-Object { $_.Name -notlike '*Graphics*' } + } + # GPU scrapers (-GraphicsDrivers Intel|AMD|NVIDIA|All). All feed the SAME $driverTempPath and the + # single DISM /Add-Driver below; a GPU is post-boot-only so none is added to $nicDriverDefs. + if ($GraphicsDrivers) { + $gpuShims = [ordered]@{ + Intel = 'Get-IntelGraphicsDrivers.ps1' + AMD = 'Get-AmdGraphicsDrivers.ps1' + NVIDIA = 'Get-NvidiaGraphicsDrivers.ps1' + } + $wantedGpu = if ($GraphicsDrivers -eq 'All') { $gpuShims.Values } else { @($gpuShims[$GraphicsDrivers]) } + foreach ($gpuName in $wantedGpu) { + $gpuPath = Join-Path $PSScriptRoot $gpuName + if (Test-Path $gpuPath) { $driverScripts += Get-Item $gpuPath } + else { Write-Warning " [!] Graphics scraper not found: $gpuName" } + } + } + + # GPU CABs are far larger than NIC CABs, so allow more wall-clock when graphics are included. + # NOTE: this Wait-Job timeout is a single GLOBAL budget shared across all scrapers. + $scraperTimeoutSec = if ($GraphicsDrivers) { 3600 } else { 1800 } # Launch all scrapers concurrently — each writes to its own subdirectory $scraperJobs = foreach ($script in $driverScripts) { @@ -200,8 +238,8 @@ try { # must NOT abort the build — Receive-Job under $ErrorActionPreference='Stop' # would otherwise rethrow a single flaky HTTP failure as terminating, after # the hour-long image apply. -ErrorAction Continue keeps it non-fatal. - Write-Host " -> Waiting for $($scraperJobs.Count) scrapers to complete (max 30 min)..." - $scraperJobs | Wait-Job -Timeout 1800 | Out-Null + Write-Host " -> Waiting for $($scraperJobs.Count) scrapers to complete (max $([int]($scraperTimeoutSec / 60)) min)..." + $scraperJobs | Wait-Job -Timeout $scraperTimeoutSec | Out-Null foreach ($job in $scraperJobs) { if ($job.State -eq 'Running') { Write-Warning " [!] $($job.Name) timed out — stopping." @@ -480,6 +518,10 @@ try { # System32\drivers, and manually create the service registry key. # NOTE: INF AddService names often differ from .sys basenames (e.g. # e1dexpress → e1d.sys), so Service and Sys are specified independently. + # GPU drivers (-GraphicsDrivers: nvlddmkm/amdkmdag/igdkmd*) are deliberately + # NOT listed here — a GPU is on neither the boot nor the iSCSI data path + # (UEFI GOP → Basic Display Adapter → lazy PnP bind), so it must stay a plain + # DISM /Add-Driver with no boot-start promotion. Do not add one. $nicDriverDefs = @( # --- Virtual Ethernet --- @{ Service = "netvsc"; Sys = "netvsc.sys" } # Hyper-V diff --git a/catalogscrape/Test-CatalogScrape.ps1 b/catalogscrape/Test-CatalogScrape.ps1 index f2581db..404d0db 100644 --- a/catalogscrape/Test-CatalogScrape.ps1 +++ b/catalogscrape/Test-CatalogScrape.ps1 @@ -119,6 +119,8 @@ Assert { $null -ne $bestTie } 'equal-version tiebreak returns a deterministic pi $expectKeys = @{ 'intel-eth.psd1' = 10; 'intel-wifi.psd1' = 2; 'marvell.psd1' = 2 'realtek.psd1' = 8; 'qualcomm.psd1' = 3; 'mediatek.psd1' = 5; 'broadcom.psd1' = 3 + # GPU graphics tables (catalog-sourced, post-boot convenience — same engine, no Source block) + 'intel-gfx.psd1' = 1; 'nvidia-gfx.psd1' = 2; 'amd-gfx.psd1' = 5 } foreach ($f in $expectKeys.Keys) { $cfg = Import-PowerShellDataFile (Join-Path $PSScriptRoot $f) @@ -151,5 +153,17 @@ $md = Import-PowerShellDataFile (Join-Path $PSScriptRoot 'mediatek.psd1') $mt7925 = $md.Targets.Devices | Where-Object Key -eq '7925' Assert { $mt7925.PreferredBranches[0] -eq '26.30' } 'MT7925 preferred branch refreshed to 26.30' +# GPU graphics tables: unified Intel device, NVIDIA consumer/pro split, AMD Radeon Pro present. +$ig = Import-PowerShellDataFile (Join-Path $PSScriptRoot 'intel-gfx.psd1') +$arcXe = $ig.Targets.Devices | Where-Object Key -eq 'Arc_Xe' +Assert { ($null -ne $arcXe) -and ($arcXe.Queries.Count -ge 2) -and ($arcXe.Queries -contains 'VEN_8086&DEV_E20B') } 'intel-gfx Arc_Xe unified (multi-HWID, incl Arc B580 E20B)' +$ng = Import-PowerShellDataFile (Join-Path $PSScriptRoot 'nvidia-gfx.psd1') +$nvGeForce = $ng.Targets.Devices | Where-Object Key -eq 'GeForce' +$nvPro = $ng.Targets.Devices | Where-Object Key -eq 'RTX_Pro' +Assert { ($nvGeForce.Queries -contains 'VEN_10DE&DEV_2684') -and ($nvPro.Queries -contains 'VEN_10DE&DEV_26B1') } 'nvidia-gfx splits consumer GeForce (2684) from RTX-pro (26B1)' +$ag = Import-PowerShellDataFile (Join-Path $PSScriptRoot 'amd-gfx.psd1') +$amdPro = $ag.Targets.Devices | Where-Object Key -eq 'ProW7000' +Assert { $amdPro.Queries[0] -eq 'VEN_1002&DEV_7448' } 'amd-gfx Radeon Pro W7900 (7448) present' + "`n== RESULT: $script:pass passed, $script:fail failed ==" if ($script:fail -gt 0) { exit 1 } else { exit 0 } diff --git a/catalogscrape/amd-gfx.psd1 b/catalogscrape/amd-gfx.psd1 new file mode 100644 index 0000000..71b54fb --- /dev/null +++ b/catalogscrape/amd-gfx.psd1 @@ -0,0 +1,40 @@ +@{ + # AMD Radeon GPU display drivers from the Microsoft Update Catalog — single-source, same engine as + # every other scraper. Verified (2026-06) that consumer HWIDs return "Advanced Micro Devices, Inc. - + # Display" WHQL CABs (amdkmdag.sys), and that Radeon Pro (W-series) HWIDs return a real Pro-keyed + # BASE WHQL display CAB (live: W7900 DEV_7448 -> 32.0.21036.18). The ISV-certified "PRO Edition / + # Radeon PRO Software for Enterprise" SKU is NOT published to the catalog — the base display driver + # drives the card fully (display + compute runtime) and is what we ship; ISV certification is out of + # scope. Selection is highest-version-first (catalog date as tiebreak). + # + # SCOPE: POST-BOOT CONVENIENCE only. A GPU cannot serve iSCSI/PXE boot, so nothing here is + # boot-critical and it gets NO boot-start promotion in build_win11pxe.ps1 (unlike the NIC scrapers). + # + # WHY ONE DEVICE PER FAMILY (not a single multi-HWID device like Intel/NVIDIA): AMD ships a current + # branch (RX 6000-9000 / RDNA2-4) and a separate legacy branch, and the catalog carries per-family + # submissions — so pooling families under one Key risks the highest-[version] winner being a package + # whose INF does not bind an older family. Keeping families separate guarantees each listed card gets + # a binding driver (cost: one download per family — trim this table to the cards you actually run). + # COVERAGE: catalog lags amd.com by ~1 quarter. The 25-relevance-row cap is sharper for AMD (many + # per-Windows-build submissions per HWID); the newest build normally still sits in the top rows. + # Representative DEV ids (VEN_1002): 7550 = RX 9000 (Navi48), 744C = RX 7900 (Navi31), + # 73BF = RX 6800/6900 (Navi21), 7448 = Radeon Pro W7900 (Navi31 GL), 73A3 = Radeon Pro W6800 (Navi21 GL). + VendorKey = 'AMD_Display' + Targets = @( + @{ + Name = 'AMD_Radeon_Consumer' + Devices = @( + @{ Key = 'RX9000'; Label = 'Radeon RX 9000 (RDNA4)'; Queries = @('VEN_1002&DEV_7550') } + @{ Key = 'RX7000'; Label = 'Radeon RX 7000 (RDNA3)'; Queries = @('VEN_1002&DEV_744C') } + @{ Key = 'RX6000'; Label = 'Radeon RX 6000 (RDNA2)'; Queries = @('VEN_1002&DEV_73BF') } + ) + } + @{ + Name = 'AMD_Radeon_Pro' + Devices = @( + @{ Key = 'ProW7000'; Label = 'Radeon Pro W7000 (RDNA3)'; Queries = @('VEN_1002&DEV_7448') } + @{ Key = 'ProW6000'; Label = 'Radeon Pro W6000 (RDNA2)'; Queries = @('VEN_1002&DEV_73A3') } + ) + } + ) +} diff --git a/catalogscrape/intel-gfx.psd1 b/catalogscrape/intel-gfx.psd1 new file mode 100644 index 0000000..5ea384c --- /dev/null +++ b/catalogscrape/intel-gfx.psd1 @@ -0,0 +1,30 @@ +@{ + # Intel GPU display drivers (DCH) from the Microsoft Update Catalog — single-source, same engine + # as every other scraper. Intel ships a UNIFIED DCH driver: one "Intel Corporation - Display" CAB + # (iigd_dch*.inf + igdkmd*64.sys) binds Arc A-series (DG2/Alchemist), Arc B-series (Battlemage), + # Iris Xe, and recent Core / Core Ultra integrated graphics. So a single device with several + # representative HWID queries dedups to ONE download (the Marvell AQC1xx pattern) and the winning + # INF binds the whole modern lineup. Selection is highest-version-first (catalog date as tiebreak). + # + # SCOPE: POST-BOOT CONVENIENCE only. A GPU cannot serve iSCSI/PXE boot, so nothing here is + # boot-critical and it gets NO boot-start promotion in build_win11pxe.ps1 (unlike the NIC scrapers). + # + # COVERAGE LIMITS (catalog-only, intentional): + # * Catalog lags intel.com by ~1-4 months and is WHQL-only (no beta). Fine for a homelab image. + # * Very old iGPUs (6th-10th gen) sit on a separate legacy branch (intel.com download 19344) and + # are NOT pulled here. Arc Pro ISV-certified drivers are not published to the catalog (out of scope). + # * Drive ONLY by HWID: a bare "Intel ... Display" NAME query returns 1000+ unpaginated rows and the + # engine parses only the first 25 relevance rows; a per-HWID query returns the Display CAB up top. + # Representative DEV ids (VEN_8086): E20B = Arc B580, 56A0 = Arc A770, 9A49 = Iris Xe (Tiger Lake), + # 7D55 = Arc iGPU (Meteor Lake). All resolve to the same unified package. + VendorKey = 'Intel_Display' + Targets = @( + @{ + Name = 'Intel_Graphics_DCH' + Devices = @( + @{ Key = 'Arc_Xe'; Label = 'Intel Arc / Iris Xe / UHD (unified DCH)'; + Queries = @('VEN_8086&DEV_E20B', 'VEN_8086&DEV_56A0', 'VEN_8086&DEV_9A49', 'VEN_8086&DEV_7D55') } + ) + } + ) +} diff --git a/catalogscrape/nvidia-gfx.psd1 b/catalogscrape/nvidia-gfx.psd1 new file mode 100644 index 0000000..823a67f --- /dev/null +++ b/catalogscrape/nvidia-gfx.psd1 @@ -0,0 +1,43 @@ +@{ + # NVIDIA GPU display drivers from the Microsoft Update Catalog — single-source (NOT nvidia.com), + # same engine as every other scraper. Verified (2026-06) that bare HWID queries return complete, + # WHQL-signed "NVIDIA - Display" CABs (nv_dispi.inf + nvlddmkm.sys), and that HWID targeting cleanly + # separates the two branches NVIDIA ships: + # * GeForce HWIDs across Ampere/Ada/Blackwell ALL resolved to the SAME unified consumer package + # (live: 32.0.15.9186) — so one device with several HWID queries dedups to ONE download. + # * RTX-pro (ex-Quadro) HWIDs resolved to a DISTINCT, newer enterprise/ODE production-branch + # package (live: 32.0.15.9579, ~1.16 GB) — a second device, its own download. + # Selection is highest-version-first. The human driver version (e.g. 581.xx) maps to the INF / + # DriverStore form 32.0.15.xxxx that the catalog reports and the engine sorts on. + # + # SCOPE: POST-BOOT CONVENIENCE only. A GPU cannot serve iSCSI/PXE boot, so nothing here is + # boot-critical and it gets NO boot-start promotion in build_win11pxe.ps1 (unlike the NIC scrapers). + # + # ACCEPTED LIMITATIONS (catalog-only): newest-WHQL-on-catalog, NOT day-0 Game Ready (GeForce lag + # ~5 months), and no GRD-vs-Studio / branch-version pinning. Data Center (Tesla) and vGPU/GRID + # drivers are not on the by-HWID catalog and are out of scope. + # OEM-SCOPED PACKAGES: a few catalog NVIDIA submissions are published by an OEM and locked to their + # SUBSYS. Highest-[version] selection normally lands on the generic NVIDIA build; if an OEM-locked + # INF ever wins for a retail card, add a TitleExclude here to drop it (no engine change needed). + VendorKey = 'NVIDIA_Display' + Targets = @( + @{ + Name = 'NVIDIA_GeForce' + Devices = @( + # Ada (RTX 4090 = 2684), Blackwell (RTX 5090 family = 2B85), Ampere (RTX 3080 = 2206) + # all bind the one unified consumer package; queried together they dedup to one download. + @{ Key = 'GeForce'; Label = 'GeForce RTX (consumer, unified)'; + Queries = @('VEN_10DE&DEV_2684', 'VEN_10DE&DEV_2B85', 'VEN_10DE&DEV_2206') } + ) + } + @{ + Name = 'NVIDIA_RTX_Pro' + Devices = @( + # RTX 6000 Ada (26B1) + RTX A6000 Ampere (2230) -> the professional production-branch + # package (distinct from, and typically newer than, the consumer one). + @{ Key = 'RTX_Pro'; Label = 'RTX / Quadro (workstation)'; + Queries = @('VEN_10DE&DEV_26B1', 'VEN_10DE&DEV_2230') } + ) + } + ) +}