-
Notifications
You must be signed in to change notification settings - Fork 1
Add catalog-sourced GPU display driver scrapers (Intel/NVIDIA/AMD) #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
Comment on lines
+241
to
+242
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If no scraper scripts are found or executed (for example, if |
||
| 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 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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') } | ||
| ) | ||
| } | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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') } | ||
| ) | ||
| } | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the default
-Pathparameter forTest-PathandGet-Itemcan cause failures if the repository is cloned into a directory path containing wildcard characters (such as[or]). Using-LiteralPathensures that the path is treated as a literal string, preventing wildcard expansion issues.