Skip to content

Latest commit

 

History

185 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deploy-Drivers-For-WindowsServer

PowerShell pipeline that makes AMD's consumer-targeted Ryzen chipset, Radeon graphics, and Ryzen AI NPU (XDNA) drivers — plus Microsoft's inbox Bluetooth PAN driver (bthpan.inf / bthpan.sys) — installable on Windows Server 2016 / 2019 / 2022 / 2025 by patching the INF ProductType=3 decoration and re-signing the catalog with a self-generated certificate.

License: MIT PowerShell 5.1+ Target: Windows Server 2025

Read this twice before running anything. This is a last-resort, lab-only tool. AMD does not officially support Windows Server 2025 for consumer Ryzen platforms (e.g. Cezanne / Renoir / Phoenix APUs in Lenovo ThinkCentre Tiny / ThinkPad / mini-PC builds). When official drivers exist, always prefer those. This repository exists for the narrow case where official Server-class drivers are unavailable and you are willing to operate a self-signed driver chain on your own hardware, at your own risk.

🆘 EXTRA WARNING for the NPU script (Deploy-AMDNpuDriverOnWindowsServer.ps1): The NPU script is markedly more dangerous and far less mature than the chipset and graphics scripts. It is unvalidated on physical NPU hardware as of this writing, the AMD account auto-download flow is best-effort and can break without notice when AMD changes form layouts, and Ryzen AI Software (the user-mode stack required to actually use the NPU) is officially unsupported on Windows Server 2025 by AMD. Treat the NPU script as experimental / research-grade, not as a production tool. See Risk classification below.

🇯🇵 日本語版 README は README.ja.md を参照してください。


Table of Contents

Related documents:

  • CHANGELOG.md — chronological per-release change log (English only)
  • SPEC.md — developer specification (architecture, conventions, design rationale; English only)
  • TESTING.md — physical-hardware validation results and regression checklist (English only)
  • CONTRIBUTING.md — how to file issues, propose changes, and run regression tests (English only)
  • README.ja.md — Japanese translation of this document, kept in sync

Why this exists

When you install Windows Server 2025 on a consumer-class AMD platform (Ryzen 4000 / 5000 / 6000 / 7000 / 8000 mobile / desktop APU, plus discrete Vega / Polaris / RDNA Radeon GPUs, plus Ryzen AI 300 / AI Max 300 with NPU) several AMD devices end up bound to Microsoft's generic in-box drivers (machine.inf, pci.inf, hdaudbus.inf, display.inf) or remain unbound entirely (NPU). The reasons are two-fold:

  1. AMD's INF files contain a ProductType=1 (Workstation) restriction in the [Manufacturer] decoration. Windows Setup honours this and refuses to bind the driver on a Server SKU (ProductType=3).
  2. AMD's catalog (.cat) signature attests to the original INF. Even if you patch the INF to add Server decorations, the signature is invalidated and the driver fails kernel-mode signing checks — which Windows Server 2025 enforces strictly via Secure Boot and HVCI.

This pipeline solves both problems by:

  • Parsing AMD's Workstation [Manufacturer] decorations and mirroring each one with ProductType=3 (Server), leaving the original Workstation entries intact (so the patched INF is bi-compatible).
  • Generating a fresh .cat catalog with inf2cat /os:Server2025_X64.
  • Signing the catalog with a self-generated code-signing certificate and importing the cert into LocalMachine\Root + LocalMachine\TrustedPublisher. This establishes package (catalog) trust for PnP — it makes pnputil accept the patched package. It does not by itself make the kernel load a non-WHQL driver: kernel image trust is evaluated independently by Code Integrity, and this project's earlier claim that a WDAC supplemental policy authorises the cert as a kernel-mode signer under Secure Boot ON has been retracted (SPEC D.58). A WDAC supplemental policy can still be deployed — now only with an explicit, operator-verified -WdacBasePolicyGuid (SPEC D.58.8).

⚠️ Disclaimer (read before running)

USE AT YOUR OWN RISK. These scripts are provided "AS IS" without warranty of any kind, express or implied. The authors and contributors are not liable for any damages, data loss, BSODs, BitLocker recovery prompts, account suspension, hardware instability, or any other problems — direct or indirect — that may arise from using, modifying, or distributing these scripts.

🆘 BRICK-LEVEL RISK (two field observations, 2025 cumulative + 2026-05-23 single-script). Two independent WS2019 + Ryzen 5 PRO 4650U (Renoir) bench observations have demonstrated that an -Action Install on a fresh-install Windows Server SKU can leave the host unable to complete the next boot — including Safe Mode — requiring an OS reinstall.

  • First observation (2025). A successful end-to-end run of Chipset InstallGraphics InstallMSBthPan Install (in that order, no reboot between scripts, with the now-removed Path C WDAC SPF orchestrator) bricked the host. The cumulative kernel-driver surface installed in a single uninterrupted Install pass — the patched AMD display driver (u0201039.inf, 1066+ HWID variants), AMD PSP firmware bindings, and a boot-loader-evaluated WDAC SPF policy carrying several brand-new self-signed catalogs at once — was the suspected interaction.
  • Second observation (2026-05-23). A subsequent fresh-install WS2019 host running only Chipset Install (Secure Boot ON, Path C still present) was bricked the same way. Graphics and MSBthPan were never executed. WinRE recovery via del C:\Windows\System32\CodeIntegrity\SiPolicy.p7b restored boot — and revealed that the WHQL co-signed AMD drivers already installed in I03 loaded successfully with no WDAC policy in place, while the non-WHQL drivers (amdi2c.sys, amdsfhkmdf.sys) remained kernel-CI-rejected regardless of the policy's contents.

The second observation falsified the original "3-script cumulative" hypothesis and led to the r70 deprecation of Path C in full. After r70, the four driver scripts no longer deploy a host-wide WDAC SPF policy on WS2019 / WS2016: WHQL co-signed drivers load via trust-store-only authorisation (Path A — Secure Boot may stay ON), and non-WHQL drivers require operator-initiated firmware Secure Boot disablement plus -UseTestSigning (Path B). The brick mechanism observed in both incidents — boot-time re-evaluation of a deployed SiPolicy.p7b against newly-installed boot-critical drivers — is structurally impossible to trigger in r70-or-later releases of this repository on legacy Server SKUs.

The risk is not zero, however. Treat any Install action on a production-shaped host (Secure Boot ON, BitLocker enabled, no spare display path, no second machine for offline repair) as having a non-trivial probability of leaving the host non-bootable until reinstall. Path A is safer than Path B; Path B requires both an in-firmware Secure Boot change (which may force a BitLocker recovery prompt — have your recovery key) and a -UseTestSigning run. See SPEC §D.30 for the full evidence chain, and TESTING §12 for both bench incident narratives.

🖥️ Physical-machine-only deployment model. This repository targets physical Windows Server hosts running on consumer Ryzen / Athlon hardware (Lenovo M75q Tiny, ThinkPad X13 Gen 1 AMD, etc.). It is not a VM-targeted toolkit. Physical machines have no native "snapshot" mechanism — there is no Hyper-V Checkpoint or VMware Revert to Snapshot you can call before -Action Install and roll back to in seconds after. Full disk imaging (Macrium Reflect, Clonezilla, dd via Linux Live USB) is possible but is a separate, hours-long, requires-second-storage-device workflow that lives entirely outside this repository. Windows Server System Restore is OFF by default, and even when enabled it does not capture C:\Windows\System32\CodeIntegrity\SiPolicy.p7b (the WDAC supplemental policy file the boot loader evaluates before System Restore can run). The practical consequence is that a failed -Action Install on a physical machine has no fast-rollback path; remediation is either offline WinRE repair (covered in Recovery from unbootable state) or OS reinstall. The supported deployment model is therefore: a physical machine you are prepared to wipe and reinstall. Do not run these scripts on a physical host whose current OS install you cannot afford to lose.

By running these scripts, you acknowledge that:

  • You are solely responsible for verifying that your use complies with AMD's End User License Agreement, Microsoft's Windows Software License Terms, and any applicable laws or regulations
  • You understand that patching AMD's INFs and re-signing them with your own certificate makes you — not AMD, not Microsoft — the cryptographic publisher of those drivers from Windows' point of view
  • You accept that WHQL certification is invalidated for any driver this pipeline replaces; if you rely on Microsoft Premier Support for affected hardware, your support contract may not cover issues caused by self-signed drivers
  • You will record your BitLocker recovery keys before running -Action Install on the chipset script (the PSP driver replacement interacts with Platform Security Processor firmware and can trigger recovery prompts on next boot)
  • You accept that the host may fail to boot at all — including Safe Mode — after an -Action Install, and that recovery in that case requires WinRE / installation media / a separate working host to repair the disk offline (or, as the project's primary remediation, an OS reinstall). The supported deployment model is therefore: a physical machine you are prepared to wipe and reinstall — not an in-production server you cannot afford to lose. Optional non-destructive rollback paths require advance preparation BEFORE -Action Install: see the "Step 0 — pre-flight" subsection of Full installation below for the recommended pre-flight checklist on physical machines.
  • You will run only one script at a time, reboot, and verify with -OnlyPhases V06 before running the next script. Running Chipset InstallGraphics InstallMSBthPan Install back-to-back without reboots has been observed to brick the host (see the field observation above).
  • You will review the script source code and understand its behavior before running it in any environment
  • For the NPU script specifically, you understand it is experimental / research-grade — see Risk classification below

Operate these tools considerately. Always prefer official AMD Server-supported drivers when they exist. This repository targets the narrow case where official Server-class drivers are unavailable and you are willing to operate a self-signed driver chain on your own hardware.

For the full at-your-own-risk acknowledgements (BitLocker, anti-cheat software, support implications, cert expiry, etc.), see the Disclaimer & at-your-own-risk acknowledgements section further down. For the recommended sequence of operations and what to do when the host is unbootable, see the Recovery from unbootable state section.


Current status: not ready for end-user use

🚧 All five scripts in this repository are under active refactoring and are NOT in a state an end user should rely on. This section answers one question only: "can I take the latest main and use it on my OS today?" The answer, for every OS, is no — and this section explains exactly why, per OS, and what has to happen before that changes.

Why the whole repository is in this state: a third-party audit (2026-08-09) found that the repository's central signing-model claim — that a WDAC supplemental policy authorises the self-signed certificate as a kernel-mode signer while Secure Boot stays ON — was wrong, and it has been retracted (SPEC D.58). The retraction is not cosmetic: it removes the advertised mechanism by which non-WHQL drivers were supposed to load with Secure Boot enabled. Remediation state as of the latest release: P0 (retraction, terminology, fail-closed base-policy gate) and the P1 waves W1-W8 have landed — Windows Driver Policy + kernel-image trust evidence, non-boolean trust classification, OS-separated policy activation with Mode T as an explicit opt-in, fail-closed download verification with per-run PFX hygiene (all four sisters since W7), the ProjectPreference / measured-PnP-rank split, the security-narrative closure, and the download-override separation with SourceArtifact evidence (W8). Still open: the P1 closeout items (kernel-trust evidence completion, base-policy machine verification) and all of P2. No post-remediation field validation has been run: historical validation successes recorded in TESTING.md predate this correction and several breaking design changes, and must not be read as statements about the current main.

Can I use the latest main on my OS today?

OS (build) Usable by end users? What the latest main would actually do
Windows Server 2025 (26100) ❌ No — refactoring in progress Install imports the cert and installs packages via pnputil; no WDAC supplemental policy is deployed unless you pass -WdacBasePolicyGuid for a base policy you verified yourself. Whether this package's non-WHQL kernel drivers then load is unverified on any current revision, and the April-2026 Windows Driver Policy adds a layer no revision has ever been field-run against (SPEC D.58.6).
Windows Server 2022 (20348) ❌ No — never field-run Same designed behaviour as WS2025, but no script has ever been executed on WS2022 hardware (TESTING §10.6 capability rows are documentation-derived).
Windows Server 2019 (17763) ❌ No With Secure Boot ON: the run ends as a designed no-op for the current AMD package (0 of 55 in-scope INFs carry a WHQL co-signature, so -SkipNonCosignedDrivers yields an empty plan; without the flag, non-WHQL kernel drivers are refused by kernel CI — WS2019 has no supplemental-policy format at all, SPEC D.39.4). With Secure Boot OFF: Path B (testsigning) is a lab-only posture, not an end-user deployment.
Windows Server 2016 (14393) ❌ No Install has never completed on WS2016, and the WDF_VIOLATION bugcheck-loop investigation on the bench remains open (SPEC D.47). An earlier revision of this row also claimed a structural KMDF ceiling (that current AMD drivers commonly declare a newer KMDF than WS2016 ships); that claim is retracted — the measured chipset baseline (tools/amd-chipset-driver-research/, 25 releases / 643 hardware-matched INF rows; TESTING §44) declares at most KMDF 1.19, equal to WS2016's documented runtime (SPEC D.52.2). Evidence scope: chipset packages only, and WS2016's host-side KMDF has itself never been measured here. The ceiling mechanism (SPEC D.47.4) remains correct; the WS2016-specific premise did not survive measurement (verdict vocabulary: READY WITH EXCLUSIONS, TESTING §37/§39).
Windows 10 / 11 (Workstation) ❌ Out of scope Install is auto-blocked by design on Workstation SKUs; only PrepareVerify runs (override exists, at your own risk).

Per-script additions on top of the table above: the NPU script is 🆘 experimental — it has never been executed on physical NPU hardware anywhere, on any OS (see Risk classification); the BthPan script has never had its device-bind path validated (no Bluetooth-controller fixture yet); the evidence collector is a read-only companion and is safe to run, but its output schema is itself mid-refactoring under the audit remediation.

What has to happen before this changes

  1. P1 audit remediation closeout — the core P1 waves have landed (OS-separated policy activation, kernel-image trust evidence, Windows Driver Policy evidence, non-boolean trust classification, fail-closed download verification, PFX key protection on chipset/graphics/BthPan); the closeout items (trust-evidence completion, base-policy machine verification) remain.
  2. P2 audit remediation — E2E coverage corrections, lab/production wording separation, sister-duplication policy.
  3. Re-validation campaigns on physical hardware per OS against the corrected model — every historical ✅ in TESTING.md predates the correction and does not transfer.

Until those land, treat this repository as a development tree and research record, not as a deployable tool. If you want the history of what has been field-run and when, TESTING.md is the authoritative record.


What's in the box

File Purpose Maturity
Deploy-AMDChipsetDriverOnWindowsServer.ps1 Chipset driver pipeline (GPIO, SMBus, PSP, MicroPEP, PMF, etc.). Source: AMD Chipset Software ~75 MB EXE, ~67 INFs. Historically field-validated (pre-remediation revisions) on M75q Tiny Gen 2 (WS2025) and X13 Gen 1 AMD (Win11 LTSC 2024); current main pending revalidation.
Deploy-AMDGraphicsDriverOnWindowsServer.ps1 Graphics driver pipeline (Display, HD Audio, Audio CoProcessor, ACP, USB-C UCSI, etc.). Source: AMD Adrenalin Edition ~600 MB EXE, ~19 INFs (Vega-Polaris Legacy branch) or ~67 INFs (Main Adrenalin branch for Phoenix+). Historically field-validated (pre-remediation revisions) — same validation hosts as chipset; current main pending revalidation.
Deploy-AMDNpuDriverOnWindowsServer.ps1 NPU (Ryzen AI XDNA) driver pipeline (PHX/HPT/STX/KRK). Source: AMD Ryzen AI Software ZIP, ~250 MB, EULA-gated download (no public direct URL). Kernel-mode driver only — does NOT install Ryzen AI Software user-mode stack. 🆘 Experimental / research-grade — NOT production-ready. No physical-NPU validation runs have been performed. AMD account auto-download is best-effort and may break with AMD form changes. Ryzen AI Software is officially unsupported on Windows Server 2025.
Deploy-MSBthPanInboxOnWindowsServer.ps1 Microsoft inbox Bluetooth PAN driver (bthpan.inf / bthpan.sys) enablement pipeline. Source: the host's own C:\Windows\System32\DriverStore\FileRepository\bthpan.inf_amd64_* directory — no remote download required. Single INF, single HWID (BTH\MS_BTHPAN). Distinguishes Phantom OK (bth.inf proxy match) from true resolution (Class=Net, Service=BthPan) on Windows Server. New — initial release. Logic shares the same Phase / Secure Boot / WDAC framework as the AMD scripts; INF patch surface is much smaller (1 INF, 1 HWID). Physical validation on ThinkPad + Intel AX210 + WS2025 build 26100.32860 is the planned first test target.
Collect-WindowsServerConfigurationEvidence.ps1 Read-only configuration evidence collector (r93+). Captures OS / device / driver-store / certificate / boot-security / CodeIntegrity / setupapi state into a timestamped evidence ZIP with a PASS / FAIL / REVIEW / INFO assessment report (exit codes 0 / 2 / 1). Runs standalone, and automatically as a pre/post pair on every deploy-script run (default since r94; -SkipEvidenceCollection opts out). New — behavioural-harness verified; physical-host validation pending.
README.md This document (English; the master).
README.ja.md Japanese translation of README.md, kept in sync.
SPEC.md Developer specification (per-script details, INF parsing strategy, WDAC policy structure). English only.
TESTING.md Physical-hardware validation results. Includes the NPU script's far weaker validation status. English only.
CHANGELOG.md Chronological per-release change log. English only.
CONTRIBUTING.md How to file issues, propose changes, and run regression tests. English only.
LICENSE MIT License.

All four PowerShell scripts share the same 21-phase architecture, the same self-signing model, and the same WDAC supplemental-policy path. They write to separate workspaces (C:\Temp\Workspace_AMD-Chipset, C:\Temp\Workspace_AMD-Graphics, C:\Temp\Workspace_AMD-NPU, C:\Temp\Workspace_Microsoft-BthPan) and use separate self-signed certificates + separate WDAC supplemental policy GUIDs so they never collide. All four workspaces sit under C:\Temp\Workspace_* for cluster-and-purge convenience; the script auto-creates C:\Temp on demand. Collect-WindowsServerConfigurationEvidence.ps1 sits alongside them as a read-only companion: it has no workspace of its own and writes its evidence next to the script (or C:\Temp).

Evidence layer: tools/amd-chipset-driver-research/ holds a read-only research toolkit and its accepted baseline — 26 AMD chipset releases, 674 hardware-matched INF rows with per-INF WDF declarations and SHA-256 provenance. It is evidence, not policy: nothing in the deployment pipeline reads it at run time. It exists so that claims about the package family (such as the WS2016 KMDF discussion above and TESTING §44) can cite a measured baseline instead of an impression. Since W11, tools/inventory-reconciliation/ joins that baseline against a deployment run's inf_inventory.csv and enforces the parity exit criterion (TESTING §46).


What's new

Latest release: 2026-08-22 — coordinated research-toolkit release amd-driver-research-v3.0.0 (no product script changes, no version bumps): the three AMD research toolkits under tools/ move together to 3.0.0 through a two-cycle Claude–ChatGPT release-review governance — Cycle A (independent initial review and corrections, closed at review revision 68) and Cycle B (v3.0.0 promotion against real-machine gates, closed at revision 80) — with every acceptance decision preserved in the review bundle's hash-chained records. Windows Client regeneration gates were accepted for all three publication surfaces (Chipset full-run Gate 2C; NPU Gate 2N with a 2/2 short gate plus a 15/15 full run at exit 0 that automatically selected the 376 package from local DEV_17F0 PnP evidence; Graphics bounded Gate 2G at 10/10, exit 0), and Windows Server 2025 bounded PathSafety,Test smokes passed 2/2 for all three, the NPU one on the corrected 37-function architecture-convergence contract (0 mismatches). The GitHub application was an explicit patch set, not a directory mirror: 177 overwrites + 45 adds + 0 deletes under a reviewed operation manifest, growing tracked tools/** from 330 to 375 files while preserving repository-owned dotfiles, the Chipset runtime staging, inventory-reconciliation/ and source-fragments/ untouched. All three research scripts now pin #requires -Version 5.1 and share a regenerated 166-function source-identical common core, byte-identical in each toolkit's data/. Dataset highlights: the chipset baseline grows to 26 releases / 674 hardware-matched INF rows (adding 8.08.12.551); graphics adds release 26.8.1 and a published signature-analysis surface; the NPU catalog is regenerated at 3.0.0 with the reviewed 280-minimum / historical RAI1.5-280 (regression-only) / production 376 artifact set and schema-validated applicability. SPEC A.11.4b/A.11.4c refresh the tools-layer analyzer baseline and register the eight error-level findings (five AST-disproven PSA2011 false positives, two PSA2010 Write-AmdWarn calls in a Windows-only error branch — real, unreachable in every qualified run, reported upstream — and one PSA2001 scope false positive). The four deployment scripts and the Collector are untouched — Chipset r122 / Graphics r87 / NPU r60 / BthPan r68 / Collector c11 — and the suite is unchanged at 28 cases / 1225 assertions.

  • 2026-08-14 — new research toolkit amd-npu-research-v1.0.0 (no product script changes, no version bumps): adds tools/amd-npu-driver-research/ at toolkit 1.0.0 — the research script, its documentation, 24 JSON schemas, curated source data, a hardware identity evidence collector, and the complete generated dataset under public/** (79 files in total). The toolkit builds a machine-readable exact-SKU applicability model for AMD Ryzen AI NPU drivers on Windows Server rather than a CPU-name-to-URL map, resolving an exact CPU SKU through codename, reviewed NPU identity, driver-release capability and AMD published support evidence to either a publicly obtainable artifact or ReviewRequired; it never executes an AMD installer and never modifies vendor payloads. The dataset covers 112 exact processor SKUs, 336 compatibility matrix rows and 112 applicability rows, and the three recommendation decisions partition the 112 processors exactly — 62 select the latest published static candidate, 22 need no NPU driver, and 28 are ReviewRequired, an intentional fail-closed outcome rather than an incomplete feature. It follows the same publication model as its predecessors: public/** is the only generated surface intended for commit, runtime staging stays untracked, generated JSON and Markdown are UTF-8 without BOM with LF, and publication-manifest.json records path, length and SHA-256 for all 22 payload files with HandEdited: false throughout, bound to the source script hash. The exact script committed here completed 13/13 stages with exit code 0 on Windows PowerShell 5.1 and on PowerShell 7.6.4 on Linux, the Windows run performing a fresh automatic vendor re-acquisition, and the two runtimes produce byte-identical public surfaces (23/23). No Windows Server NPU runtime support is claimed — the reviewed INF selector floor and the absence of a ProductType server exclusion support static-candidate reasoning only, and the Ryzen AI Z2 Extreme evidence is Windows client runtime only. .gitattributes stores this toolkit's public/** verbatim, as it already does for the chipset and graphics toolkits. The four deployment scripts and the Collector are untouched — Chipset r122 / Graphics r87 / NPU r60 / BthPan r68 / Collector c11 — and the suite is unchanged at 28 cases / 1225 assertions.

  • 2026-08-13 — new research toolkit amd-graphics-research-v1.0.0 (no product script changes, no version bumps): adds tools/amd-graphics-driver-research/ at toolkit 1.0.0 — the research script, its documentation, 29 JSON schemas, curated seed and regression data, 18 authored reports, and the complete generated dataset under public/** (135 files in total). The toolkit discovers AMD graphics driver products and releases, acquires and extracts real vendor artifacts, and analyses their INF content for Windows Server applicability; it is research tooling and is not part of the deployment pipeline. The dataset covers 23 selected artifacts across 21 product groups, carrying 482 INF driver records and 1,928 Windows Server applicability rows in each of three compatibility matrices, with per-artifact counts agreeing with the aggregate index on every key. It follows the same publication model as the chipset toolkit: public/** is the only generated surface intended for commit, runtime staging stays untracked, generated JSON and CSV are published byte-for-byte while generated Markdown is UTF-8 without BOM with LF, and publication-manifest.json records size, SHA-256, generation mode and originating source hash for all 64 payload files with HandEdited: false throughout. All 29 schemas compile and validate all 35 published JSON documents with zero errors, so the dataset can be checked with the schemas shipped beside it. .gitattributes stores this toolkit's public/** verbatim, as it already does for the chipset toolkit. The four deployment scripts and the Collector are untouched — Chipset r122 / Graphics r87 / NPU r60 / BthPan r68 / Collector c11 — and the suite is unchanged at 28 cases / 1225 assertions.

  • 2026-08-12 — research toolkit amd-chipset-research-v2.0.0 (no product script changes, no version bumps): tools/amd-chipset-driver-research/ moves to toolkit 2.0.0 and publishes its complete generated dataset for the first time. The 1.0.0-era inventory/accepted-baseline/ snapshot model is retired in favour of a single allow-listed generated surface, public/**, defined by the new PUBLICATION-POLICY.md; runtime staging (inventory/, reports/, work/, private/evidence/) stays untracked. The dataset is 65 files — 25 per-release canonical Raw JSON analyses covering AMD chipset releases 2.04.04.111 through 8.07.16.1035, aggregate indexes, 28 reports, and a publication-manifest.json recording size, SHA-256, generation mode and originating source hash for all 64 payload files (HandEdited: false on every entry — a wrong generated value is fixed in the generator and the run repeated, never patched in place). 643 INF package records match the published inventory CSV on an exact key-set equality; MSI declarative analysis parses 25/25 read-only across 13,993 selected rows with zero all-null rows; and the 700 Windows Server applicability figures (WS2016/2019/2022/2025) are recomputable from the published Raw JSON alone. Vendor evidence is byte-faithful: path portability is field-scoped, so AMD selector, MSI and embedded-XML tokens such as /SETFILTERUSB, /SETRYZENPPKG, /SETPCI, /info.xml and /DevID.xml are recorded exactly as they appear in the vendor binary while execution-host paths are normalized. Aggregate indexes additionally canonicalize the Windows PowerShell 5.1 { value, Count } collection wrapper to plain arrays — recognition requires an enumerable value whose length matches Count, so a domain object merely carrying those property names is left alone — and publication fails closed if a wrapper survives; canonical per-release Raw JSON is never rewritten by that projection. Gate G-20 is repointed from the retired baseline CSV to public/inventory/amd-chipset-driver-inventory.csv (643 rows, same schema); the inventory-reconciliation tool takes its inventory path as a parameter and needed no code change. The four deployment scripts and the Collector are untouched — Chipset r122 / Graphics r87 / NPU r60 / BthPan r68 / Collector c11 — and the suite is unchanged at 28 cases / 1225 assertions.

  • 2026-08-11 — Chipset r122 / Graphics r87 (immutable-deployment-plan): wave W14 of the audit remediation closes R5-M03 (feedback R5 / 5B-5). P06 now fixes a canonical deployment-plan.json after the -SkipNonCosignedDrivers trim and before the first INF mutation — the audit's logical contract SourceArtifact -> PackageInventory -> DeploymentPlan -> PatchedArtifacts made real. Every row carries the audit's field set: Inf / SelectedSourceInfPath / SelectedSourceInfSha256 (the content identity), Devices[] from the rich W13 detail, SourceVariant, SelectionReason, ExpectedMutation, WdfDecision with the typed observation attached, PackageCompletenessDecision (chipset reports its phantom-reference evaluation — the machinery the audit endorsed over the research shortcut; graphics honestly reports Evaluated=false), KernelTrustObservation (CoSigned/NotCoSigned/NotAnalysed from the P05 WHQL analysis — an observation, never a loadability claim), and per-selection PayloadFiles[] SHA-256 (the W13 Q-W13-1 deferral repaid: chipset enumerates [SourceDisksFiles*] via Get-InfReferencedFile, graphics hashes the source-folder reality the sibling copy transports). The P06 patch/copy loops now iterate plan rows — "P06 patches no INF outside the plan" is structural, and behavior-preserving by measurement (NeedsPatch already implies VariantSelected AND EligibleForCatalog at P05, so the plan's patch row set equals the old filter's). A degenerate co-sign trim writes the empty plan — planned-empty is distinguishable from never-planned. The P06 marker moves to schemaVersion 2: input { InventorySha256, SkipNonCosignedDrivers, DeploymentPlanSchemaVersion }, output { DeploymentPlanSha256, PatchedCount, CopiedCount, DegeneratePlan, PatchedInfManifestSha256 }; a hit additionally re-hashes the plan on disk and the patched INF layer — the 5B-5 resume-drift protection: a resumed run can no longer silently proceed against a different package selection. deployment-plan-execution.json (fail-open) records per-row Outcome + PatchedInfSha256 keyed to the plan SHA — the installed -> patched INF SHA -> source INF SHA reverse lookup. P08 and I03 run a report-only alignment check that names out-of-plan INFs under patched/ (sibling-copy transport); install behavior is unchanged and enforcement is deliberately deferred to the static-first wave. The container layer is deliberately absent from the plan while the authoritative extraction is executable-based (the shadow graph is fail-open and non-authoritative) — a recorded scope reduction. New gate G-23; the suite measures 28 cases / 1225 assertions. NPU r60 / BthPan r68 / Collector c11 unchanged (BthPan is a documented out-of-scope per ruling Q-W14-5: a single-package universe with provenance already chained by the W13 set fingerprints).

  • 2026-08-10 — Chipset r121 / Graphics r86 / BthPan r68 (content-addressed-cache): wave W13 of the audit remediation closes R5-H03 and R5-H06 and lands the R5-M01 typed WDF observation. Phase markers move to schemaVersion 2: a shared pure primitive (Get-PhaseFingerprintHash — ordinal key order, canonical key=value lines, lowercase SHA-256; fixture-testable with no I/O) fingerprints each phase's declared input and output field sets, and Test-PhaseMarker -ExpectedInputFields turns a marker into a content-addressed cache entry — a legacy schema-less marker is a miss by design, -Force still always misses, and every miss names which side diverged. P03 no longer trusts the newest download by LastWriteTime: a cache hit re-hashes the exact recorded file and must match the recorded SHA-256 (the repack / same-name-swap / stale-mix scenarios die here); the requested URL is recorded identity, not a revalidation trigger — an upstream release does not invalidate a byte-identical local artifact (declared deviation from the 5B-3 letter, flagged for the next audit pass). P04 fingerprints on { ArtifactSha256, ExtractionSchemaVersion } and records the INF-layer manifest (sorted relpath+SHA of every extracted *.inf); a hit requires both the input equality and the recomputed manifest to match. P05 chains the manifest and writes the new canonical package-inventory.json — every record keeps its historical fields and gains SourceArtifactSha256 / InfSha256 / InspectionStatus / typed Wdf.KMDF|UMDF evidence ({ Status, Versions[], Evidence[] } with 1-based line numbers, five-value vocabulary, Unknown is never Compatible); an unreadable INF becomes a ParseFailed record instead of aborting the phase. The CSV/TXT reports are demoted to derived views of the canonical JSON through a single property-preserving projection, and every rehydration site (the P05 cache hit, P06's required load, chipset's three best-effort loaders) goes JSON-first, restoring the rich detail the old CSV round-trip silently dropped; the legacy CSV remains a read-only fallback for pre-W13 workspaces. MSBthPan adapts the same contract to its no-download universe with DriverStore source/copied set fingerprints. The W12 shadow graph deliberately stays outside every fingerprint (fail-open evidence must not drive cache misses). New gates G-18 / G-19 / G-21; the five marker functions join the three-way sister-identity list; the suite measures 27 cases / 1151 assertions. NPU r60 / Collector c11 unchanged (NPU carries no marker machinery — measured, not assumed).

  • 2026-08-10 — Chipset r120 (static-extractor-shadow-port): wave W12 of the audit remediation begins the static-extraction migration (v5 R5-H01 steps 1-3, R5-H02). The research toolkit's static ISSetupStream decoder (C#, ISx-informed, MIT — attribution retained in-block and recorded in the new root THIRD-PARTY-NOTICES.md) is ported verbatim into the chipset script through a new source-fragment mechanism: tools/source-fragments/AmdStaticExtraction.fragment.ps1 is the single source of truth, the script embeds the marker-delimited payload byte-identically, and gate G-17 pins the equality. On top of the decoder, newly authored shadow machinery: a queue-based bounded recursive orchestrator (SHA-256 dedup, MaxDepth, probe-first EXE routing with 7-Zip fallback, MSI OLE/CFBF magic validation), a read-only Windows Installer COM File-table reader (OpenDatabase mode 0 — no msiexec, no process launch), and a pure CAB-entry name resolver for the suffix-versioned name.infN variant convention — the layer whose absence produced the historical 31-INF blind spot against the 119-row field universe. P04 now runs this shadow after the current extraction, always on and fail-open: the executable-strategy tree stays authoritative for every downstream phase, no deployment decision reads the shadow output, and the evidence lands in <WorkRoot>\manifests\extraction-graph.json (SchemaVersion 1.0; per-container records in the audit-mandated 13-field shape; an Infs[] table with resolved names and variant indices; a ParityNote comparing shadow INF counts against the current tree). The shadow tree under <WorkRoot>\shadow-extracted\ is cleaned per run and retained afterwards for inspection (disk cost is roughly one extracted installer). New gates: G-17 (identity, structure, prohibited capabilities, measured decoder/resolver/orchestrator behavior, report-only research agreement), G-22 (ISx attribution travels with the code), G-16 shadow scope (AST proof that the shadow never reaches a process launch, msiexec, or the executable extraction strategies). Suite measures 24 cases / 986 assertions. Graphics carries no shadow yet — the port is deliberately deferred as W12G after the chipset shape settles. Graphics r85 / NPU r60 / BthPan r67 / Collector c11 unchanged.

  • 2026-08-09 — Chipset r119 / Graphics r85 / BthPan r67 (download-override-separation): wave W8 of the audit remediation closes H-04R (v5 R5-M05) and lands the SourceArtifact provenance record (R5-M02 shape). -Force no longer bypasses the Authenticode download gate — its marker-cache, policy-replace, Path-B and Mode T powers are unchanged. The sole override is the new -AllowUnverifiedDownload switch (chipset/graphics), which reaches exactly the AMD installer sites and continues a FAILED verification as operator-attested-unverified with a loud warning; hosts where Get-AuthenticodeSignature cannot run surface as HostCannotVerify under the same attested vocabulary. The Microsoft SDK/WDK and 7-Zip sites — including MSBthPan's — pass no override and stay unconditionally fail-closed (machine-pinned). Every completed verification now writes source-artifact_<file>.json beside the artifact (SchemaVersion / URLs / RetrievedAtUtc+ObservedAtUtc / SizeBytes / Sha256 / FormatValidation via MZ/CFB magic / Authenticode fields / Attestation) — a W13 provenance precursor that also closes the missing download-SHA gap at the artifact level (R5-H03 partial). Evidence writing is fail-open; the gate stays fail-closed. New gate G-09 Test-DownloadOverrideSeparation.ps1 pins all of the above (negative control against the pre-W8 tree: 33 named failures); Write-SourceArtifactEvidence joins the three-way identity list. The suite measures 20 cases / 873 assertions.

  • 2026-08-09 — NPU r60 / BthPan r66 (npu-pfx-hygiene-and-msbthpan-rename): wave W7 of the audit remediation closes H-05R. The NPU script joins the W4 PFX contract carried by the other three sisters: New-RandomPfxPassword and Set-PfxFileAcl are adopted byte-identically (three-way → four-way), the Ctx injects a per-run random 32-char CSPRNG password when -PfxPassword is omitted, the export is fail-closed on an empty password and ACL-restricts the PFX to Administrators+SYSTEM, and the PFX is deleted after a completed Install (the certificate stays in the store). The fixed known-literal export branch — and the never-implemented "re-encode" comment beside it — are retired. Because the password is invocation-scoped, V01 treats a missing PFX as the expected post-Install state and V02 inspects the public CER when the PFX cannot be opened cross-run (private-key possession was proven by the P09 signing run). Structural adaptation recorded rather than papered over: NPU has no phase-marker cache, so P07 regenerates the certificate on every signing run and the leftover-PFX open-probe is satisfied by unconditional regeneration. The MSBthPan boot-signing evidence field AmdSuppPolicyId is renamed MsBthPanSuppPolicyId (the marker file already carried the product-correct name). New gate G-07 Test-NpuPfxHygiene.ps1 pins the contract with AST/rename detectors that carry synthetic self-checks (negative control against the pre-W7 tree: 12 named failures, plus 5 / 2 / 1 named failures in the extended W4-contract, sister-identity and doc-state cases). The suite measures 19 cases / 763 assertions.

  • 2026-08-09 — Chipset r118 / Graphics r84 / NPU r59 / BthPan r65 (security-narrative-closure): wave W6 of the audit remediation closes the narrative debt. The retracted signing model survived the P0 retraction inside help text, comments and runtime strings — the supplemental policy was still called "the default path", still advertised "keeps Secure Boot ON", and the guidance block still said the script "adds its self-signed cert" for kernel loading. All of it is swept: the supplemental story is uniformly optional App Control supplemental policy, explicit -WdacBasePolicyGuid required, AppControlDecision layer only (SPEC D.58), and the I02 no-tools branch announces the refusal it actually performs instead of a testsigning path it no longer takes. The Mode T gate wording is re-verified against the Microsoft TESTSIGNING page: with Secure Boot ON the bcdedit write is refused at command execution (not "silently dropped at next boot"), and the HVCI refusal is now stated as conservative project policy (Microsoft requires test-signing under HVCI rather than rejecting it). This document's own state section, the I02 activation table, the PFX rows and the maturity labels are synced to the tree. Two new gates hold it: G-05 Test-RetiredSigningNarrative.ps1 scans normalized logical blocks so line wrapping and markdown emphasis cannot hide a retired phrase (negative control against the r117 tree: 45 named findings — including two comment sites the manual survey had missed), and G-06/G-10 Test-DocumentationStateConsistency.ps1 pins the status markers, activation vocabulary, PFX doc/code cross-check, the tests/README case-table count and the maturity vocabulary in both languages (negative control: 27 named failures). The suite measures 18 cases / 743 assertions.

  • 2026-08-09 — Chipset r117 / Graphics r83 (project-preference-and-measured-rank): wave W5 of the audit remediation makes the driver-selection story honest about whose decision it is. The [C] > [B] > [A] category override is renamed ProjectPreference — it is the project's policy to submit its self-signed AMD-specific drivers over Microsoft generic / vendor drivers, not an objective ranking: Windows computes its own rank at install time, and pnputil will not force a lower-ranked driver onto a device. V06 no longer says a device "WILL be replaced" — the bucket is now PROJECT_PREFERS_INSTALL ("plan submits a replacement"), and the decision Reason no longer claims the self-signed driver "outranks" anything. The measured counterpart lands too: at I04 completion, Show-MeasuredDriverRankReport captures the actual PnP candidate list via pnputil /enum-devices /drivers (parsed by a new fixture-tested pure function; optional Rank: in hex/decimal, with the documented first-listed = best-ranked fact carrying when absent), marking [ours] per device — and states plainly when the pnputil build does not support the flags instead of fabricating anything. Chipset/Graphics only (the decision layer exists nowhere else); the parser fixture is synthetic and real-host validation is an operator-pending item (TESTING §43). The suite measures 16 cases / 680 assertions.

  • 2026-08-09 — Chipset r116 / Graphics r82 / BthPan r64 (download-verification-and-pfx-hygiene): wave W4 of the audit remediation closes two supply-chain / key-hygiene findings (NPU is unaffected — it has no download fallbacks and never carried the fixed default). P1-F: every downloaded binary is now Authenticode-verified fail-closed on every run, cache hits included, immediately before execution or expansion — the Windows SDK/WDK installers ('Microsoft Corporation'), the 7-Zip MSI ('Igor Pavlov', enforced at the call site so the canonical installer units stay untouched), and the AMD installer ('Advanced Micro Devices', both cached and fresh paths, with -Force as a loud-warning escape hatch for CDN quirks). P1-G: the fixed ChangeMe!2026 PFX password is retired — the default is now a per-run random password (32-char CSPRNG), the exported PFX is ACL-restricted to Administrators+SYSTEM, and the PFX is deleted after Install (the certificate stays in the store; P07 regenerates on demand and first probes whether a leftover PFX opens with this run's password). New structural-contract case Test-DownloadAndPfxHygiene.ps1 (negative control against the r115 tree: 31 named failures); the suite measures 15 cases / 654 assertions.

  • 2026-08-09 — Chipset r115 / Graphics r81 / NPU r58 / BthPan r63 (activation-path-os-separation): wave W3 of the audit remediation separates supplemental-policy activation by OS from primary sources re-verified on Microsoft Learn (SPEC D.58.9): CiTool.exe ships beginning Windows 11 22H2 / Windows Server 2025 — not on WS2022 as this repository previously claimed — and supplemental policies exist only in the Multiple Policy Format (Windows 10 1903+ / WS2022+), so WS2016/WS2019 can never run one. I02 now refuses the supplemental path on single-policy-format hosts instead of deploying an inert .cip; a new four-way pure helper Resolve-SupplementalActivationPlan (fixture-tested) picks citool / refreshpolicy-exe / wmi-bridge, and the CIM bridge is re-documented as the WS2022-without-RefreshPolicy path. Mode T becomes an explicit opt-in: previously an install run enabled BCD testsigning implicitly whenever WDAC tools were absent — the boot-signing posture could be weakened without the operator ever asking for Mode T. That fall-through is retired (refuse-and-return), and every testsigning write now sits under a UseTestSigning conditional pinned in the AST by the new gate G-04 case Test-InstallPathMutationGuard.ps1 (also: no Windows Driver Policy GUID to a removal verb, no nointegritychecks, no HVCI registry write; negative controls measured on mutated copies). Ruling U3 lands as a conditional runtime disclosure: the Windows Driver Policy evaluation-mode facts print only on Server 2025+ when the policy is proven present — never on 2016/2019/2022. The suite measures 14 cases / 615 assertions.

  • 2026-08-09 — Chipset r114 / Graphics r80 / NPU r57 / BthPan r62 (boot-signing-posture): wave W2 of the audit remediation retires the last runtime remnants of the retracted signing model. The can-load boolean (EffectiveCanLoadSelfSigned) is gone from all four sisters; the boot-signing environment derives BootSigningPosture instead — testsigning-active (the measured Mode T lab path is open) / supplemental-deployed-unverified (a supplemental App Control policy file is deployed; no kernel-load effect is claimed from it) / closed — and a deployed supplemental policy no longer flips install-readiness to READY. The AS-IS/TO-BE guidance, dry-run, help text and diagnostics are rewritten to the honest model: WHQL/WHCP-signed drivers load with no host change, project self-signing establishes PackageCatalogTrust only, and the only measured path for project-signed kernel images is Mode T (-UseTestSigning, Secure Boot OFF, lab hosts). Test-WhqlCoSignature additionally emits the P1-D Classification vocabulary (WhcpHdc / LegacyCrossSignedNotProven / PrivateOrTestSigned / Unsigned / Unknown; the AllowListed value is reserved and never emitted — ruling Q4). New offline case Test-BootSigningPostureSweep.ps1 holds gate G-03 repo-wide (negative control against the r113 tree: 36 named failures); the suite measures 13 cases / 577 assertions.

  • 2026-08-09 — Chipset r113 / Graphics r79 / NPU r56 / BthPan r61 (signing-model-correction): a third-party audit of the signing model found the repository's central claim — that Path A authorises the self-signed cert as a kernel-mode signer via a WDAC supplemental policy while Secure Boot stays ON — is supported by no run in this repository's record, and the field evidence that exists shows the opposite structure (after the 2026-05-23 SiPolicy.p7b deletion, WHQL co-signed drivers loaded with no policy present at all, while non-WHQL drivers stayed refused by kernel CI regardless of the policy). The claim is retracted (SPEC D.58), and the vocabulary is split so it cannot be rewritten: PackageCatalogTrust (what catalog self-signing actually establishes), KernelImageTrust (evaluated independently by Code Integrity), AppControlDecision. The single behavioural change ships the retraction into code: the supplemental policy used to target a Windows-shipped base policy GUID that nothing ever verified exists; there is no default base policy any more, and I02 refuses the supplemental deployment unless -WdacBasePolicyGuid names a base policy the operator has verified (deployed with rule option 17, Enabled:Allow Supplemental Policies) — a four-way byte-identical admissibility gate whose refusal closes the phase and returns, per the r112 discipline. NPU gains the -WdacBasePolicyGuid parameter it never had (the GUID was hardcoded at the call site). New test case Test-SupplementalPolicyGate.ps1 pins all of it, with a negative control reporting 23 named failures against the r112 tree; the suite measures 9 cases / 458 assertions. Also corrected: this README claimed the PFX is not password-protected while the code ships 'ChangeMe!2026' (audit L-01). Custom Kernel Signers scope (Windows 11 24H2+ only) and the Server 2025+ Windows Driver Policy are documented as separate layers: SPEC D.58; re-run guide: TESTING §41.

  • 2026-08-09 — Chipset r112 / Graphics r78 / NPU r55 / BthPan r60 / Collector c10 (gate-before-mutation): a clean Windows Server 2019 run with Secure Boot ON. I02 announced a refusal and then carried on — it declares install plan was not fully examined, and then fell through to path selection, so a plan the script had just called unfit to judge went on to be authorized. On that host the run stopped at the Path B prerequisite, but that check is about Secure Boot, not about the plan: had Secure Boot been OFF, I02 would have written the BCD testsigning flag and asked for a reboot for an install plan containing nothing. The refusal now closes the phase and returns. Separately, $Ctx.DegeneratePlan was consulted in P08/P09/V01/V04 and in no Install phase — the same defect for the third time, each round teaching the phases someone had thought of. Rather than add three more names to a list, every phase that changes persistent state now sits behind one gate, with a startup check for contradictions the environment alone settles (-UseTestSigning on a Secure Boot host) and a per-phase call so -OnlyPhases I02 cannot bypass it. An Install run that changes nothing now says nothing was installed and nothing changed — which matters, because testsigning and trust-store imports survive a reboot and a mutation applied for an empty plan means a clean install to recover. Also fixed: every run printed two Get-WinEvent errors that were not errors (no bugcheck events on a healthy machine is the good outcome; a PowerShell 5.1 transcript records caught terminating errors), and the banner now reports -SkipNonCosignedDrivers and -UseTestSigning, without which a transcript cannot be interpreted afterwards. Post-mortem: SPEC D.57; re-run guide: TESTING §40.

  • 2026-08-09 — Chipset r111 / Graphics r77 / NPU r54 / BthPan r59 / Collector c9 (wdf-observed-vs-documented): the previous release stopped reading the host UMDF version because no binary carries it — correct, and incomplete, since it removed a false negative without putting anything in its place. Field measurement of three Windows releases supplied the missing piece, including a Windows Server 2025 host measuring KMDF 1.35 against Microsoft's published 1.33. The capability table is therefore split into observed and documented columns rather than corrected: observed is measured and wins; documented is what Microsoft publishes and never receives a measured value, because its only use is to be compared against measurement. UMDF requirements are judged again, but only where this host's measured KMDF equals its documented KMDF — that agreement is the observable proof the published table has kept up with this build, and the UMDF entry beside it comes from the same table. Where measurement has moved past the table, UMDF is left unjudged with the reason stated, which is what Server 2025 now reports. Also fixed: the KMDF version was derived from the wrong half of the PE. A file carries its version twice and the two disagree — on Server 2019 the same Wdf01000.sys reads 1.27.17763.1192 numerically and 1.27.17763.1 as a string — so derivation now uses the numeric fields and both readings are printed. WUDFx02000.dll, the library a UMDF 2 driver actually binds to, is probed for presence. Design rationale: SPEC D.56; field reading guide: TESTING §39.

  • 2026-08-09 — Chipset r110 / Graphics r76 / NPU r53 / BthPan r58 / Collector c8 (degenerate-plan-verify-and-umdf-measurement-fix): two defects found by one clean Windows Server 2019 run. The Verify side treated a correct empty plan as a failure-SkipNonCosignedDrivers found no WHQL co-signature on any in-scope INF, so P06 closed as skipped and P08/P09 respected that, all exactly as designed; then V01 threw run earlier phases first about a phase that had run and decided correctly, aborting before V02–V06 could execute. V01 now verifies what does exist and reports the absent patched INFs as expected; V04 closes skipped like P08 and P09. The host UMDF version was never measurable — it was read from WudfRd.sys the way KMDF is read from Wdf01000.sys, which on this host yields 10.0: the operating system version. Wdf01000.sys really is 1.27.… but WudfPf.sys, WUDFRd.sys and WUDFHost.exe are all 10.0.17763.9020, and the documented UMDF version for that build is 2.27, carried by no binary. Because 10.0 compares above every real requirement, every UMDF driver silently passed on every host. UMDF is now reported as unknown and unjudged requirements are counted and stated, because a question that was not asked is not a pass. The collector carried the same derivation and is corrected too. Post-mortem: SPEC D.55; re-run guide: TESTING §38.

  • 2026-08-08 — Chipset r109 / Graphics r75 / NPU r52 / BthPan r57 (wdf-requirement-vs-host): both halves of the framework question existed and nothing put them together — the collector reads what the host provides, the sisters read what each INF requires, and comparing them still meant opening two artifacts by hand after the run. P05 now reads the host framework version once and checks the inventory against it, naming every package that asks for more than the machine provides, with the version it declares and the version it was measured against. If the runtime cannot be read the check is skipped rather than guessed — treating unknown as zero would flag every WDF driver on the machine. The run summary gains a third verdict, READY WITH EXCLUSIONS: NOT READY is reserved for the boot-signing case where nothing loads, whereas a WDF shortfall is partial and the correct action is to proceed and expect a named subset to be missing. No phase is gated on this: the requirement columns have been verified against fixtures and never measured against the real 55-INF AMD package, and gating a pipeline on a value nobody has observed inverts the order. Design rationale: SPEC D.54; how to read it on a real host: TESTING §37.

  • 2026-08-08 — Chipset r108 / Graphics r74 / NPU r51 / BthPan r56 (inf-side-wdf-requirement): the collector learned in c7 what framework version the host provides — one side of a comparison that had nothing on the other side. This release adds the packages' side: what each driver INF asks for, as five new columns in inf_inventory.csv from all four scripts (IsWdfDriver, KmdfLibraryVersion, UmdfLibraryVersion, CoInstallerVersions, WdfSectionCount). The failure this addresses is quiet: inf2cat /os:Server2016_X64 sets the catalog's target OS and does not lower a driver's KMDF requirement, so a package declaring KmdfLibraryVersion = 1.33 can be inventoried, patched, catalogued, signed and reported ready on a 1.19 host — every phase green — and then fail to load. That is not a signing failure, so neither Path A nor Path B moves it. The directive names are read directly from the INF text; following KmdfService = to the section it names looks obvious and produces no match and no error on packages that name sections differently, and no match reads as "not a WDF driver" — the safe-looking answer. Version comparison is numeric in all five scripts from one byte-identical helper, because as strings 1.19 sorts below 1.9. Correction: the assertion counts published for r106 and r107 were computed rather than measured (212 and 271 were the real figures, not 204 and 239); the suite now prints its own measured total and the environment it was measured on. Design rationale: SPEC D.53; measurement procedure: TESTING §36.

  • 2026-08-08 — r107 / r73 / r50 / r55 / c7 (winre-tool-compatibility-and-wdf-evidence): the recovery collector ran in a real recovery environment for the first time — on a host that would not boot — and stopped at stage 7, because WinRE does not ship findstr. Stages 8-16 never ran, on the one machine that needed them. The mistake was not using findstr; it was assuming which commands WinRE has, and a tool census now records what is actually present. Also new: KMDF/UMDF file versions rather than just dir output, every WdfCoInstaller*.dll with the framework version its name encodes, the services depending on Wdf01000 (the suspect pool when WDF_VIOLATION fires), the 0x10D parameter decode table travelling inside the bundle, and a WDF assessment in the configuration collector. Correction: Windows Server 2016 ships KMDF 1.19, not the 1.15 an earlier session asserted from memory — 1.15 is the Windows 10 1507 value. None of this predicts WDF_VIOLATION, which comes from a driver that loaded and then broke the framework contract; it bounds the suspect pool, and the JSON says so itself. Post-mortem: SPEC D.52; run record: TESTING §35.

  • 2026-08-07 — r93 / r59 / r37 / r41 (windows-server-configuration-evidence-collector): configuration evidence collector. A standalone, read-only companion script that captures the Windows Server configuration areas the deploy scripts operate on (OS identity, devices, driver store, project certificates, boot security, CodeIntegrity events, setupapi logs, script + workspace inventory) into a timestamped evidence ZIP with a color-coded PASS / FAIL / REVIEW / INFO assessment report. All four deploy scripts gained integration that takes a diffable pre/post evidence pair around the run (shipped in r93 as the opt-in -CollectEvidence; made default-on with the opt-out -SkipEvidenceCollection in r94). See "Configuration evidence collector (r93+)" below.

Recent releases (2026-07 — 2026-08)

  • 2026-08-08 — r106 / r72 / r49 / r54 (recovery-collector-argument-modifier-fix): the r105 mode split worked on its first real run — Collection mode : online, hives taken via reg save, the live registry queried without a hive load, and CrashDumpEnabled = 0x7 reported on the console, answering the question that motivated running this before a reboot. Stage 12 then aborted: inside a CALLed subroutine cmd.exe resolves argument modifiers before deciding a line is a comment, and rem is not exempt, so the r105 comment explaining why a file's reported size cannot be trusted — which contained the modifier it was describing — stopped the script. Reworded, with a regression guard scanning the subroutine section for any modifier lacking its argument number and a companion assertion that the legitimate FOR-variable form survived. This is the fourth defect in this file found only by running it, and the third caused by cmd.exe parsing a line differently from how it reads; each is now forbidden by shape rather than by discipline. Post-mortem: SPEC D.51; run record: TESTING §34.

  • 2026-08-08 — r105 / r71 / r48 / r53 (recovery-collector-online-offline-modes): Collect-OfflineRecoveryEvidence.cmd completed all thirteen stages on a booted host and produced a bundle with a coherent set of gaps, all from one fact — the machine was running, so the kernel held the registry hives open and DISM refused /image: against its own live installation. Two gaps mattered: CrashDumpEnabled was never read, and the pending update's state was never determined — the question that motivated running this before a reboot. Running the recovery collector on a booted host is not misuse; it is the sensible rehearsal, and each mode reaches evidence the other cannot. The script now detects which situation it is in by comparing %SystemRoot% with the target volume, and uses reg save instead of copying locked hives, the live CurrentControlSet instead of a loaded ControlSet001, and dism /online instead of /image:. CrashDumpEnabled and AutoReboot are echoed to the console — a value of 0 means the next bugcheck writes no dump, which is worth seeing before the reboot rather than after. A file size that cannot be measured is now reported as unknown rather than as 0 MB, and the copy is attempted anyway. Post-mortem: SPEC D.50; run record: TESTING §33.

  • 2026-08-08 — r104 / r70 / r47 / r52 (offline-collector-cmd-parser-fix): Collect-OfflineRecoveryEvidence.cmd ran for the first time and stopped part way through stage 5. A label containing parentheses — CBS (incl. CBS.persist.log) — was expanded inside an if block, and cmd.exe substitutes variables before parsing a parenthesised block, so the ) closed the block early and the remainder was parsed as a command. Fixed on two levels: no label contains a parenthesis, and no subroutine uses a parenthesised block at all — they branch with goto now, so a future label containing (, & or | cannot re-create the fault. The test suite had passed the broken file because it checked encoding, goto resolution and reg load balance but modelled nothing about cmd.exe's expansion order; a shell parser cannot be fully modelled in a test, but the shape that allows the fault can be forbidden, and now is. The partial run did confirm auto-detection working on real hardware: the 112 GB removable volume was chosen over the 931 GB system disk by the write probe. Post-mortem: SPEC D.49; run record: TESTING §32.

  • 2026-08-08 — r103 / r69 / r46 / r51 (offline-collector-microsoft-noboot-coverage): Collect-OfflineRecoveryEvidence.cmd now collects the full set Microsoft asks for in a no-boot report — measured against their published list, the first version had 13 of 17 items missing. The pattern is worth naming: it gathered what was needed to diagnose a driver problem and skipped almost everything about servicing, and an interrupted update is one of the commonest reasons a Server stops booting after a configuration-change reboot. Added: full system-drive listing, every event log, CBS.persist.log, SrtTrail.txt, WindowsUpdate / USOShared / DISM logs, ReportingEvents.log, raw SYSTEM / SOFTWARE / COMPONENTS / RegBack hive copies, pagefile.sys. It now runs with no arguments: it finds the Windows volume by its config hive (in WinRE that is usually not C:) and finds a destination by writing a probe file, since boot media is often mounted read-only. Large files are size-capped with the actual size recorded rather than filling the stick mid-run, and absence is written to the manifest because an absent file is frequently the finding. Also fixes the r102 .cmd, which landed with LF endings — apply this patch with git am --keep-cr. Post-mortem: SPEC D.48; procedure: TESTING §31.

  • 2026-08-08 — r102 / r68 / r45 / r50 / c6 (driver-framework-crash-evidence-and-offline-collector): driven by a WDF_VIOLATION bugcheck loop on Windows Server 2016 and by this project's first WS2016 measurements. The collector now records driver-framework.json — the KMDF/UMDF runtime version, which is a hard ceiling: a driver whose INF declares a newer KmdfLibraryVersion cannot load, and that is not a signing failure, so neither Path A nor Path B moves it (inf2cat /os:Server2016_X64 changes the catalog target, not the KMDF requirement) — and crash-evidence.json, whose bugcheck events carry the stop code and all four parameters; for WDF_VIOLATION the first parameter names which framework contract was violated. New Collect-OfflineRecoveryEvidence.cmd collects from an offline Windows volume in the Recovery Environment, which has no PowerShell — a strategy that assumes PowerShell is unusable exactly when the evidence matters most. Also: the first WS2016 host contradicted a documented OS fact (PS_UpdateAndCompareCIPolicy is present on 14393.9339, not absent), and independently reproduced the vwifibus prediction from SPEC D.43.3 — a check written before that host existed found the exact predicted condition. Post-mortem: SPEC D.47; measurements: TESTING §30.

  • 2026-08-08 — r101 / r67 / r44 / r49 / c5 (guard-placement-preflight-and-os-capability-evidence): a clean-install WS2019 run of all three production scripts found that the r100 degenerate-plan guards were in the wrong functions — P06 correctly detected the empty plan and closed SKIPPED, then P08 failed naming a phase that had just run, because the guards had landed in P09 and V03. Both were valid PowerShell referencing real properties, so every static gate was green on a file whose fix was unreachable; placement is now asserted against PowerShell's own parser and re-checked by the test suite. BthPan also failed P01 on its own default — it auto-places the transcript under <WorkRoot>\logs\ and then refused to run because the transcript was inside -WorkRoot, a check only BthPan carries, so identical invocations gave two successes and one failure. For the planned Windows Server 2016 campaign, the collector adds os-capability.json (which per-build profile the scripts would select, fourteen cmdlets, six CIM classes including the one absent on WS2016, and whether signtool is present — a WHQL verdict without it is a default, not a measurement) and archive-capability.json (proves Compress-Archive works by using it). SPEC D.46.4 consolidates the OS difference table; TESTING §29 is the campaign guide. The collector itself completed for the first time on this run: 13 stages, 0 failed, 560 services recorded with ImagePathExists populated 560/560.

  • 2026-08-08 — r100 / r66 / r43 / r48 / c4 (evidence-resilience-and-degenerate-plan-handling): a clean-install WS2019 run on the previous generation aborted the evidence collector at stage 9 of 12 with no archive, then failed PrepareVerify at P09. Three collector defects, none of them visible to static analysis: a call passing a parameter the callee does not have (so the c3 "fix" to this same block still did nothing and still reported PASS); a -like pattern containing an unterminated [ character class, which throws before matching anything and killed the run; and all twelve stages inside one try with the archive inside it too, so one failure cost every later stage and the ZIP. Stages are now isolated, the archive moved to a top-level finally matching the four deploy scripts, and a new Collection completeness row leads the report. Separately, the r99 analysis widening returned its answer: 0 of 55 in-scope INFs carry a WHQL co-signature (signtool present, so this is a measurement) — -SkipNonCosignedDrivers cannot produce an installable plan on this driver package, and P06 now says so and stops cleanly instead of P09 throwing. New: tests/, the repository's first executable test suite — 3 cases, 55 assertions, no dependencies, with a negative control proving it fails against the defective release. Post-mortem: SPEC D.45; suite: TESTING §27.

  • 2026-08-08 — Collector c3 (service-configuration-evidence-and-path-resolution-fix): collector-only. The device-load diagnostic added in c2 never ran. Three string literals shipped wrong — two registry paths lost their trailing separator and a regex used \S (the non-whitespace class) where a literal backslash was meant — so the service lookup always failed, ServiceBinaryPresent was never populated, and the assessment row Driver binary presence reported PASS on a host with a missing binary. No static gate could catch it: psa.py and the parser verify that a literal is well-formed, not what it was meant to contain. Root cause was the authoring tool, not the script; fragments are now copied byte-for-byte from .ps1 files and the required and forbidden literals are asserted against the bytes written. Verified by a 22-case runtime harness (22/22) with a negative control that fails against the defective c2. Separately, the collector previously recorded no service configuration at all — the gap behind that incident, whose cause was a Windows Server default-configuration fact (an inbox wireless component not staged on Server SKUs). New stage emits services.json (every service, unfiltered — user-mode, kernel drivers and registry-only keys, with resolved ImagePath and an on-disk existence test, plus a reverse dependency index) and server-feature-services.json (feature install state paired with the services those features stage). Post-mortem: SPEC D.44.

  • 2026-08-08 — r99 / r65 / r42 / r47 / c2 (plan-coverage-collateral-health-and-load-diagnostics): the fifth WS2019 field run completed the Path A chain end-to-end and proved that pnputil accepts this pipeline's self-signed catalogs (53 of 53) — then the operator found drivers would not load and a previously working Intel Wi-Fi adapter had stopped. Three defects combined. (1) -SkipNonCosignedDrivers analysed only the patch-needing subset — 2 INFs out of a 119-INF inventory — so 53 never-examined drivers installed while the plan was declared Secure-Boot-safe; NonCoSignedCount = 0 had been read as "nothing in the plan is non-WHQL" when it only ever meant "nothing examined failed". The analysis now covers the whole install scope, eligibility is verdict-driven, and plan JSON SchemaVersion 3 carries PlanUnverifiedCount on which the I02 short-circuit is fail-closed. (2) An Intel adapter was re-enumerated 32 ms after a pnputil /install related-drivers pass and its re-install failed on a service binary absent from this Server SKU; /install is deliberately not removed (it is the path just proven to work, and the link is an attribution rather than a proof), but a whole-system device-health census either side of I03 now reports any device that got worse, AMD or not. (3) The readiness digest said READY while the same screen said driver loading was BLOCKED; it now consults the boot-signing state too. The evidence collector gains device-load diagnostics: CM_PROB and NTSTATUS decoding that separates signature failures from look-alike API mismatches, per-device service ImagePath existence checks, and setupapi failure extraction. Post-mortem: SPEC D.43. These changes are verified by static gates only — no harness, no field run yet (TESTING §25).

  • 2026-08-08 — r98 / r64 / r41 / r46 (phase-status-and-digest-binder-fixes): the fourth WS2019 field run is the first in which the -SkipNonCosignedDrivers Path A chain reached I02 with both preceding decisions correct — I01 ran and imported the certificate, and the I02 short-circuit fired, confirming in the field the two things r97 set out to fix (independently corroborated by the evidence collector's pre/post certificate-store pair). The phase then failed on the call that closes it: the short-circuit passed 'short-circuit' to Write-PhaseFooter, whose canon ValidateSet permits only done/cached/skipped/failed — a defect latent since r72, unreachable until the short-circuit first fired. Because that helper is a vendored canon region, the repair is at the nine call sites (short-circuit -> cached; the two never-yet-exercised reboot halts -> skipped), not in the framed body. Separately, the r97 self-locating containment finally named the readiness-digest thrower: @( ) over a System.Collections.Generic.List[object] throws in the binder itself — present since r92, so both earlier attributions (r95 Get-Variable probe, r96 variable: probe) were wrong — replaced by .ToArray() in all four sisters, hence r41 for NPU. Post-mortem: SPEC D.42; canon verification procedure: SPEC A.11.8a.

  • 2026-08-08 — r97 / r63 / r40 / r45 (path-a-scope-and-digest-fixes): the third WS2019 field run completed PrepareVerify -SkipNonCosignedDrivers end-to-end for the first time, then exposed two wrong assumptions in the day's earlier fix: catalogs are regenerated and self-signed for the whole selected scope (vendor catalogs do not cover the Server OS target), so I01 must run on any non-degenerate plan — the r96 gate skipped it; and the plan counts aggregated out-of-scope W11x64 variant rows, whose surviving names re-introduced the trimmed non-co-signed INF and blocked the I02 short-circuit, dropping the run into the by-design Path B / Secure Boot abort. r97 scopes the plan JSON to the install variant set (SchemaVersion 2, new PlanCatalogSignCount), gates I01 on "no catalogs to self-sign" only, corrects the install-phase messages, and rewrites the readiness-digest probe onto the exception-free variable: provider with self-locating containment (still unavailable on 5.1 after r95; NPU is included this time, hence r40). Post-mortem: SPEC D.41; revised contract: SPEC D.31.17.

  • 2026-08-08 — r96 / r62 / r39 / r44 (path-a-plan-semantics-fixes): fixes from the first -SkipNonCosignedDrivers field execution — schema-tolerant P06 trim (the r71 consumer crashed on real inventory rows), corrected trim semantics (no-patch INFs are always eligible), workspace persistence of the analysis and post-trim plan across the PrepareVerify -> Install boundary, and the first I01 gate. Post-mortem: SPEC D.40.

  • 2026-08-08 — r95 / r61 / r39 / r43 (ws2019-ps51-field-fixes): fixes from the first Windows Server 2019 field run — a Windows PowerShell 5.1 engine bug (Get-Variable -Scope on a missing variable) truncated the RUN SUMMARY readiness verdict on every 5.1 run of r92-r94; existence probes no longer litter the transcript with caught-but-recorded error records; and the I02 PATH B banner now states explicitly that pre-1903 builds (WS2019 = 1809) cannot use the WDAC supplemental path at all. Post-mortem: SPEC D.39.

  • 2026-08-07 — r94 / r60 / r38 / r42 (evidence-collection-default-on): configuration-evidence collection became automatic on every run (ListPhases excepted) — the opt-in -CollectEvidence was replaced by the opt-out -SkipEvidenceCollection.

  • 2026-08-07 — r92 / r58 / r36 / r40 (quickedit-guard-readiness-and-artifact-archive). Three field-driven hardening additions: the console QuickEdit guard (an accidental text selection freezes every console write and looks exactly like a mid-phase hang; SPEC D.38 documents the 18m37s field case, including why Ctrl-C "un-hangs" the run instead of stopping it), the explicit install-readiness verdict at the end of the RUN SUMMARY, and the run-artifact archive — one diagnostics ZIP per run, copied next to the script (*.pfx private keys are never included).

  • 2026-08-07 — r91 / r57 / r35 / r39 (auto-run-transcript-and-chipset-url-discovery). Every run is now transcribed automatically (no -LogFile needed), and the Chipset URL discovery accepts AMD's 2026-07 installer renaming (amd_chipset_software_<v>.exeamd_software_<v>.exe; SPEC D.37) with probe-miss evidence preservation under logs\.

  • 2026-07-03 — waves 1 / 2a / 2b: r88-r90 / r54-r56 / r36-r38 (BthPan) / r32-r34 (NPU) (cross-repo-canon-vendored-region-markers-wave-*). The cross-repo shared-helper canon was reframed as machine-verifiable vendored regions with >>> CANONICAL ... <<< markers (32 units in Chipset / Graphics / BthPan, 29 in NPU), maintained from the central ai-generated-artifacts repository. Improvements to code inside a marked region flow through the central canon, not through direct edits here.

Older release notes (every release since the initial commit) live in CHANGELOG.md.

Risk classification of the four scripts

This section exists because the NPU script is materially riskier than its sister scripts and operators must understand the difference before running it. The BthPan script is the lowest-risk of the four because its driver source is the host's own DriverStore (no remote download), the INF surface is exactly one file with one HWID, and Microsoft itself signs the inbox driver — only the catalog must be re-signed.

Aspect Chipset script Graphics script NPU script BthPan script
Maturity Historically field-validated, multiple pre-remediation cycles; pending revalidation Historically field-validated, multiple pre-remediation cycles; pending revalidation 🆘 Experimental — not yet validated on physical NPU hardware New — initial release. Logic shares the proven Phase / Secure Boot / WDAC framework. Single-INF surface is small enough that physical validation is feasible in one session.
Distribution format Public EXE direct download Public EXE direct download EULA-gated ZIP, requires AMD account No downloadbthpan.inf is already staged at C:\Windows\System32\DriverStore\FileRepository\bthpan.inf_amd64_* on every Windows install.
Public download URL Yes (direct) Yes (direct) No — requires AMD account login + EULA acceptance per release N/A — driver is on the host.
AMD account auto-download N/A N/A Best-effort; depends on AMD's form HTML staying stable; can break without notice N/A.
OS support stance AMD does not officially support, but drivers run AMD does not officially support, but drivers run Driver loads on Server 2025, but Ryzen AI Software (user-mode stack) does NOT work on Server 2025 per AMD docs Microsoft inbox driver — fully supported by Microsoft on Workstation SKUs. Filtered out on Server SKUs only because of the NTamd64...1 ProductType decoration. This script supplies the missing ProductType=3 decoration without touching Microsoft's binary at all.
Hardware availability Common (any AMD APU machine) Common (any AMD GPU/APU machine) Limited to Ryzen AI 300 / Ryzen AI Max 300 / Ryzen 7040/8040 series Common — any machine with a Bluetooth host controller bound and BTH\MS_BTHPAN enumerated. Most ThinkPads, mini-PCs, NUCs ship one.
Test fixtures available in repo M75q Tiny Gen 2, X13 Gen 1 AMD M75q Tiny Gen 2, X13 Gen 1 AMD NONE — no physical NPU machine in the maintainer's lab as of this writing ThinkPad + Intel AX210 + WS2025 build 26100.32860 (planned first physical validation).
Failure modes specific to this script PSP / TPM driver replacement may trigger BitLocker recovery Display reset on signed-cat install NPU device may not enumerate; Ryzen AI Software won't work Phantom OK trap — bth.inf may proxy-match and report Status=OK even though bthpan.sys is NOT loaded. V06 / I04 must explicitly distinguish Phantom OK (DriverInfPath=bth.inf, Class=Bluetooth) from true resolution (DriverInfPath=oem*.inf, Class=Net, Service=BthPan).
Recommended use Lab + cautious production Lab + cautious production Lab / research only. Do not deploy on production hosts. Lab + cautious production. Risk is low because the script does not replace any vendor driver — it only enables the Microsoft-published inbox driver on a SKU class where Microsoft chose not to ship it by default.
Recommended Action mode Install after PrepareVerify review Install after PrepareVerify review PrepareVerify ONLY until you can confirm the host is a real NPU machine and you accept that Ryzen AI Software won't function on Server 2025 PrepareVerify first to confirm Phantom-OK vs true-resolution state, then Install.

Practical rules of thumb for the NPU script:

  1. Do not run -Action Install on a host you cannot afford to roll back. The cleanup path is implemented but driver-store removal is best-effort and may require manual pnputil /delete-driver oemNN.inf /force cleanup.
  2. The Ryzen AI Software user-mode stack (Python conda env + ONNX Runtime VitisAI EP + OGA) is officially Windows-11-only. Even if the kernel driver loads on Server 2025, you will not be able to run inference workloads through the supported stack. Do not expect AI workload functionality on Server 2025; the kernel driver is at most an experiment in driver bring-up.
  3. There are no physical-NPU validation runs yet. All current verification is static analysis with psa.py and code-review of the AMD-published quicktest.py detection logic translated to PowerShell. Real hardware behaviour is unconfirmed.
  4. AMD's account auto-download flow can break without notice. AMD periodically updates their account.amd.com form structure, CSRF token names, and EULA acceptance endpoint. The script's Tier 2 authentication is best-effort. Always prefer Tier 4 (-OfflineZip) for reproducible runs.

If after reading the above you still want to run the NPU script: see NPU-specific quick start.


Scope of coverage

Hardware in scope

  • AMD Ryzen Mobile: Ryzen 4000 (Renoir), 5000 (Cezanne / Lucienne / Barcelo / Barcelo-R), 6000 (Rembrandt), 7000 (Phoenix / Hawk Point), 8000 (Hawk Point refresh), AI 300 (Strix Point / Krackan Point), AI Max 300 (Strix Halo).
  • AMD Ryzen Desktop APU: Ryzen 5000G / 5000GE (Cezanne), 7000G / 8000G (Phoenix).
  • AMD Radeon Graphics: Vega 6 / 7 / 8 / 11 (integrated, Renoir → Cezanne → Barcelo), RDNA 3 (Phoenix 780M / 760M), RDNA 3.5 (Strix Point), discrete RX 5000 / 6000 / 7000 / 9000 series.
  • AMD AM4 / AM5 chipsets: X470, X570, X670/X670E, X870/X870E, B450, B550, B650, B850.
  • AMD ACPI devices: GPIO controllers (AMDI0030, AMDF030), I2C (AMD0010), Micro PEP (AMD0004), HSMP (AMDI0097), PMF (AMDI0100 / AMDI0102), SFH (AMDI0080 / AMDI0011), UART (AMD0020), Wireless Button (AMDI0051), Pluton stub (MSFT0200 / MSFT0201).
  • AMD NPU / XDNA Compute Accelerator (experimental, NPU script only):
    • Phoenix / Hawk Point (PCI\VEN_1022&DEV_1502&REV_00) — Ryzen 7040 / 8040 / 8040 PRO mobile series. Driver build 32.0.203.280 (RAI 1.5).
    • Strix Point / Strix Halo (PCI\VEN_1022&DEV_17F0&REV_00/10/11) — Ryzen AI 300 / Ryzen AI Max 300 series. Driver build 32.0.203.314 (RAI 1.6.1) or newer.
    • Krackan Point (PCI\VEN_1022&DEV_17F0&REV_20) — Ryzen AI 200 series. Driver build 32.0.203.314 (RAI 1.6.1) or newer.
  • Microsoft inbox Bluetooth PAN (BthPan script only):
    • HWID: BTH\MS_BTHPAN — child device exposed by every Microsoft-supported Bluetooth host controller after the host controller binds. Vendor-agnostic (Intel AX2xx, Realtek RTL88xx, MediaTek MT7xxx, Broadcom BCM43xx, etc.).
    • Prerequisite: a Bluetooth host controller driver is bound and showing Status=OK in Device Manager. If the host controller itself is unknown-device, install its vendor driver first; this script does NOT cover host controllers.
    • Symptom this script solves: on Windows Server SKU, BTH\MS_BTHPAN shows as Unknown Device (code 28), or shows Status=OK but with DriverInfPath=bth.inf and Class=Bluetooth (Phantom OK; bthpan.sys is NOT loaded and BthPan service is NOT running).
    • Verified true-resolution criteria: DriverInfPath=oem*.inf, Class=Net, Service=BthPan, C:\Windows\System32\drivers\bthpan.sys present, BthPan service registered, a Bluetooth PAN NetAdapter visible to Get-NetAdapter.

Operating systems in scope

The driver scripts (Chipset, Graphics, NPU, BthPan) support both modern Windows Server (2022 build 20348, 2025 build 26100) and legacy Windows Server (2019 build 17763, 2016 build 14393):

OS Build I02 path Notes
Windows Server 2025 26100 Path A — trust-store import (package trust); WDAC supplemental deployment only with an explicit -WdacBasePolicyGuid Primary validation target. Kernel image trust is evaluated independently of package trust (Mode S — SPEC D.58.7). The Windows Driver Policy applies on Server 2025+ (SPEC D.58.6).
Windows Server 2022 20348 Path A — trust-store import (package trust); WDAC supplemental deployment only with an explicit -WdacBasePolicyGuid No field run on record — designed for the same Multiple Policy Format tier as WS2025 (without inbox CiTool — activation via the downloadable RefreshPolicy.exe or the WMI bridge; SPEC D.58.9) but never executed on WS2022 hardware (see Current status). Kernel image trust is evaluated independently of package trust (Mode S — SPEC D.58.7).
Windows Server 2019 17763 Path A (trust-store only, if all drivers are WHQL co-signed) / Path B (-UseTestSigning, requires Secure Boot Disabled in firmware) r70 deprecated the previous WDAC SPF orchestrator path; see SPEC §D.30. WHQL co-signed drivers (e.g. AmdMicroPEP.sys, amdgpio2.sys) load via trust-store import alone; non-WHQL drivers (e.g. amdi2c.sys, amdsfhkmdf.sys) require Path B. r71 added -SkipNonCosignedDrivers for hosts that prefer to keep Secure Boot ON and accept that non-WHQL drivers will not be installed; r72 added the I02 short-circuit so that -SkipNonCosignedDrivers + Secure Boot ON completes end-to-end without any firmware change (the WHQL embedded signatures authorise the drivers at kernel CI directly); r96 fixed the Path A plan defects found in the first field execution (schema crash, plan-emptying trim rule, process-boundary loss — SPEC §D.40); r97 corrected the plan aggregation scope and the I01 criterion after the second attempt (out-of-scope variant rows poisoned the counts; catalogs are self-signed for the whole selected scope, so I01 skips only on a plan with nothing to self-sign — SPEC §D.41). See SPEC §D.31, §D.31.11 and §D.31.17.
Windows Server 2016 14393 Same as WS2019 Same r70 behaviour. Field validation pending on a physical WS2016 host.
Windows 10 / 11 (Workstation) any PrepareVerify only Install phases auto-blocked.

Legacy server hosts (WS2019 / WS2016) no longer delegate I02 to an external orchestrator (the prior Path C / WDAC SPF orchestrator was removed in r70 after field validation demonstrated it could leave the host unable to boot — see SPEC §D.30 for the full evidence chain). On these hosts, I02 now uses Path A (trust-store-only, Secure Boot may remain ON) when the install plan consists entirely of WHQL co-signed drivers, or Path B (bcdedit /set TESTSIGNING ON plus a reboot, requires Secure Boot Disabled in firmware first — see SPEC §D.30.4 / F9) when any non-WHQL driver is present.

Hardware out of scope

  • AMD EPYC server chips (server-class CPUs found in cloud instances, Hetzner AX dedicated, etc.): EPYC uses a different chipset model and ships first-party Server-supported drivers via Microsoft Update. This pipeline targets consumer Ryzen, not EPYC.
  • Real-time GPU compute stacks (ROCm, HIP SDK, OpenCL beyond the user-mode driver shipped in the Adrenalin package): consult AMD's ROCm documentation for Server.
  • Ryzen AI Software user-mode stack (Python conda env, ONNX Runtime VitisAI Execution Provider, OnnxRuntime GenAI/OGA, Vitis AI Quantizer, Lemonade SDK, etc.): out of scope of the NPU script. The NPU script installs the kernel-mode driver only. Ryzen AI Software must be installed separately by the operator from the AMD installer at https://account.amd.com/en/forms/downloads/xef.html?filename=ryzen-ai-lt-1.7.1.exe, and per AMD documentation it is officially supported on Windows 11 build >= 22621.3527 only.

Folder layout

Repository structure (after git clone):

Deploy-Drivers-For-WindowsServer/
├── Deploy-AMDChipsetDriverOnWindowsServer.ps1     Chipset driver pipeline (21 phases)
├── Deploy-AMDGraphicsDriverOnWindowsServer.ps1    Graphics driver pipeline (21 phases)
├── Deploy-AMDNpuDriverOnWindowsServer.ps1         NPU (Ryzen AI XDNA) pipeline (21 phases)
├── Deploy-MSBthPanInboxOnWindowsServer.ps1        Microsoft inbox bthpan pipeline (21 phases)
├── Collect-WindowsServerConfigurationEvidence.ps1 Read-only configuration evidence collector (r93+)
├── README.md                                      This document (English; master)
├── README.ja.md                                   Japanese translation, kept in sync
├── TESTING.md                                     Physical-hardware validation results (EN only)
├── SPEC.md                                        Developer specification (EN only)
├── CHANGELOG.md                                   Chronological per-release change log (EN only)
├── CONTRIBUTING.md                                Issue / PR guidelines (EN only)
├── SECURITY.md                                    Vulnerability reporting (EN only)
├── CODE_OF_CONDUCT.md                             Community behaviour (EN only)
├── AGENTS.md                                      Agent-governance bridge (canonical governance lives in the central repo)
├── CLAUDE.md                                      Pointer to AGENTS.md
├── LICENSE                                        MIT License
├── .psa.config.json                               psa.py configuration (PSAP rules opt-in)
├── .gitattributes                                 Git line-ending normalization
└── .gitignore                                     Standard ignores

What the scripts produce

After -Action PrepareVerify (or -Action All), each script populates its workspace:

C:\Temp\Workspace_AMD-Chipset\   (or C:\Temp\Workspace_AMD-Graphics\, C:\Temp\Workspace_AMD-NPU\, C:\Temp\Workspace_Microsoft-BthPan\)
├── download\              AMD installer EXE / NPU driver ZIP
│                          (BthPan: empty — driver source is DriverStore, not downloaded)
├── extracted\             Original INFs and binaries from the EXE / ZIP / DriverStore
│                          (BthPan: extracted\bthpan\bthpan.inf / .sys / .cat)
├── patched\               Patched INFs with mirrored ProductType=3 sections
│                          + generated .cat files + signtool signatures
│                          (BthPan: patched\bthpan\ — single INF directory)
├── cert\                  Self-signed code-signing cert (PFX + CER) +
│                          WDAC supplemental policy XML/CIP
├── logs\                  Automatic run transcript (r91+), tool logs,
│                          probe-miss evidence html (chipset, r91+),
│                          run-artifact archive plan marker (r92+)
├── secureboot_ms_sample\  UEFI Secure Boot baseline JSON evidence
│                          (Microsoft sample-script output)
└── inf_inventory.csv / inf_inventory_report.txt
                           P05 inventory and per-INF analysis
                           (BthPan: single-row CSV — exactly one INF)

After -Action Install (or phases I01-I04), the script also deploys:

  • The cert to LocalMachine\Root + LocalMachine\TrustedPublisher.
  • Only when -WdacBasePolicyGuid names a base policy you have verified exists: a WDAC supplemental Code Integrity policy to C:\Windows\System32\CodeIntegrity\CiPolicies\Active\, activated via CiTool --update-policy where available (no reboot on Windows Server 2022+ / Windows 11 22H2+). The policy references this cert; the earlier claim that this authorises the cert as a kernel-mode signer under Secure Boot ON is retracted (SPEC D.58) — kernel image trust is evaluated independently of this file.
  • The patched + self-signed drivers via pnputil /add-driver /install.

Two artifact families land next to the script rather than in the workspace: the per-run diagnostics archive <ScriptName>_<Action>_run-artifacts_<timestamp>_<PID>.zip (r92+; excludes *.pfx, download\, extracted\ and any file over 50 MB), and — collected by default on every run since r94 (-SkipEvidenceCollection opts out) — the collector's WindowsServerConfigurationEvidence_<stage>[_<invoker>]_<timestamp> evidence directories + ZIPs (r93+).


Quick start

Prerequisites

  • Windows Server 2025 host (build 26100), or Windows 11 24H2 (build 26100) for preview-only verification (the script will block Install phases on Workstation OS unless -AllowWorkstationInstall is passed; see TESTING.md for the WS2025 pre-migration verification workflow).
  • PowerShell 5.1 or higher (Desktop or Core), 64-bit, running as Administrator.
  • Internet connectivity (for AMD installer download and Windows SDK / WDK installation via winget).
  • ~5 GB free disk space on the workspace volume (~7 GB if you also run the NPU script — Ryzen AI ZIPs are ~250 MB plus extracted contents).

Get the scripts

# Option 1: clone the repository
git clone https://github.com/usui-tk/Deploy-Drivers-For-WindowsServer.git
cd Deploy-Drivers-For-WindowsServer

# Option 2: download a release ZIP from
# https://github.com/usui-tk/Deploy-Drivers-For-WindowsServer/releases

One-shot dry run (safe; modifies nothing)

# In an elevated PowerShell session
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

.\Deploy-AMDChipsetDriverOnWindowsServer.ps1   -Action PrepareVerify -CleanWorkRoot
.\Deploy-AMDGraphicsDriverOnWindowsServer.ps1  -Action PrepareVerify -CleanWorkRoot
.\Deploy-MSBthPanInboxOnWindowsServer.ps1      -Action PrepareVerify -CleanWorkRoot

# r94+: every run automatically takes a read-only pre/post configuration-evidence
# pair (two diffable evidence ZIPs next to the script; see the collector section).
# Add -SkipEvidenceCollection to any of the commands above to opt out:
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1   -Action PrepareVerify -CleanWorkRoot -SkipEvidenceCollection

# NPU script — REQUIRES an offline ZIP (or other download source) to actually run P03.
# On a clean machine without -OfflineZip, P03 will throw "All 4 download tiers exhausted".
# See the NPU-specific quick start below for the full pattern.
.\Deploy-AMDNpuDriverOnWindowsServer.ps1 -Action PrepareVerify -CleanWorkRoot `
    -OfflineZip .\NPU_RAI1.6.1_314_WHQL.zip -AssumeIfMissing

PrepareVerify runs P00-P09 (locate / extract source, patch, generate catalog, sign) followed by V01-V06 (verify artefacts, dry-run install plan, hardware impact analysis). No system state is modified — no certs are imported, no WDAC policy is deployed, no drivers are installed. Read the V05 / V06 output to understand exactly what Install would do.

BthPan-specific note: the BthPan script's P03 (FetchInstaller) does NOT download anything — it locates bthpan.inf in the host's own C:\Windows\System32\DriverStore\FileRepository\bthpan.inf_amd64_* directory. P03 fails only on hosts where the inbox driver has been deliberately removed (extremely rare).

Full installation (chipset, graphics, BthPan)

🆘 Do NOT run these three scripts back-to-back without reboots. That sequence was directly observed to leave WS2019 + Renoir unable to boot — including Safe Mode — and there is no automated rollback. The supported sequence is described below.

Physical-machine reality check (read before Step 0). This repository targets physical Windows Server hosts, not VMs. Physical machines have no "snapshot" feature you can call from PowerShell, no Restore-VMSnapshot to roll back to seconds after a bad Install. Server SKU System Restore is OFF by default and even when on does not roll back SiPolicy.p7b. Full disk imaging (Macrium Reflect, Clonezilla, dd) is possible but requires an external drive sized for your C: and is a separate workflow that runs outside Windows. The Step 0 checklist below codifies what is actually practical and effective on a physical machine: ensure you have a working repair path before you need it, record the keys you would otherwise be locked out by, and run scripts one at a time so the blast radius of any failure is bounded.

# ---- 0. Pre-flight (physical machine) — complete BEFORE -Action Install ----
#
#   A. Create a Windows recovery USB on a SECOND machine.
#      You cannot create one after the target is bricked.
#         - In Windows 10/11/Server 2022+: search for "Create a recovery
#           drive" (`RecoveryDrive.exe`) on a working host. Use a 16+ GB
#           USB stick. This gives you WinRE: command prompt, Startup
#           Repair, System Image Recovery, and `bcdedit`.
#         - Alternative: download the Windows Server 2019/2022/2025 ISO
#           matching the failed host's edition from the Volume Licensing
#           Service Center (VLSC) or Microsoft Evaluation Center, then
#           use Rufus / MediaCreationTool to write it to a USB stick.
#           Installation media also boots straight into WinRE via
#           "Repair your computer" on the first screen.
#         - Test the USB boots on a known-good machine before you need it.
#
#   B. Record BitLocker recovery keys IF BitLocker is enabled on C:.
#         manage-bde -protectors -get C: | Out-File C:\BitLockerKeys.txt
#      Print the file or save it to a separate device. The chipset
#      script's PSP driver replacement can trigger BitLocker recovery
#      on next boot.
#
#   C. (Strongly recommended, but optional.) Take a full disk image of
#      the system drive to external media:
#         - Macrium Reflect Free (rescue media boot + image C: to USB-
#           attached drive), or Clonezilla, or `dd if=/dev/sdX` from a
#           Linux Live USB. Expect 20-60 minutes for typical NVMe sizes.
#         - This is the ONLY mechanism that allows full rollback of a
#           bricked physical host without OS reinstall. It is not
#           required by the scripts, but it is the difference between
#           "30 minutes to restore" and "an afternoon to reinstall +
#           reconfigure".
#
#   D. Confirm you have an OS install ISO + matching license key on
#      hand. If steps A-C all fail at recovery time, reinstall is the
#      explicitly-supported recovery path of last resort. Knowing in
#      advance that you can rebuild the host within the day is part of
#      "a physical machine you are prepared to wipe".
#
#   E. Note: -CleanWorkRoot does NOT make this any safer. The destructive
#      side effects of Install are on the OS itself, not the workspace.

# ---- 1. Install the chipset drivers FIRST and reboot ----
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1 -Action Install
# After completion, REVIEW the I04 output:
#   - Count of LOADED, REBOOT_NEEDED, LOAD_FAILED, FAILED
#   - If LOAD_FAILED > 0: STOP. Diagnose before continuing.
#   - If REBOOT_NEEDED > 0: reboot now.
Restart-Computer
# After the host comes back up, confirm baseline:
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1 -OnlyPhases V06
# Only if V06 reports the expected post-install state, proceed.

# ---- 2. Install the graphics drivers and reboot ----
.\Deploy-AMDGraphicsDriverOnWindowsServer.ps1 -Action Install
# I04 review (same as step 1). If LOAD_FAILED > 0 OR Section 2 shows
# functional probe failures, STOP. Recovery is much easier from this
# checkpoint than from later in the chain.
Restart-Computer
.\Deploy-AMDGraphicsDriverOnWindowsServer.ps1 -OnlyPhases V06

# ---- 3. Install BthPan (smallest surface, lowest risk) ----
.\Deploy-MSBthPanInboxOnWindowsServer.ps1 -Action Install
# If I04 prints "*** TRUE RESOLUTION NOT YET ACHIEVED ***", reboot
# and re-run. PnP rebind sometimes requires a fresh boot.

All scripts are idempotent and cleanup-safe (-Action Cleanup removes the workspace, the certs from the trust stores, and the deployed WDAC policy). However, Cleanup runs from a booted host; if Install left the host unbootable, see Recovery from unbootable state.

What about running everything in one pass? Conceptually, all three Install actions converge on the same end state — patched INFs in the driver store plus package-catalog trust for the self-signed certificate (kernel-image trust is evaluated independently by Code Integrity — SPEC D.58). In practice, doing it as one uninterrupted sequence has a strictly worse failure mode: each Install can introduce a regression that only becomes visible at the next boot, and the per-script post-install verification (I04 / V06) cannot fully predict boot-time behaviour because it runs in the live OS, before the boot loader re-evaluates kernel CI against the newly-bound driver set. Running one script at a time with a reboot between bounds the blast radius of any single regression to "the most recently installed family", which is the difference between "roll back one driver via WinRE" and "reinstall the OS".

BthPan-specific outcome check: after the BthPan script's Install action completes, I04 (PostInstallVerification) explicitly distinguishes Phantom OK from true resolution. The script prints *** TRUE RESOLUTION ACHIEVED *** only when bthpan.sys is loaded, BthPan service is running, and BTH\MS_BTHPAN reports Class=Net, Service=BthPan, DriverInfPath=oem*.inf. If you instead see *** TRUE RESOLUTION NOT YET ACHIEVED ***, a reboot is the typical fix (PnP rebind sometimes requires a fresh boot).

NPU script Install: see NPU-specific quick start. The Install action requires extra preconditions (offline ZIP availability or AMD account credentials) and is not recommended without physical NPU hardware.

Recovery from unbootable state

If a reboot after -Action Install leaves the host unable to boot (display blank, infinite reboot loop, BSOD-on-boot, Safe Mode also fails, etc.), the realistic recovery options on a physical machine are listed below in the order operators should actually attempt them. Note the ordering is different from a VM context: WinRE-based offline repair comes first here because most physical-host operators will not have a disk image ready.

  1. WinRE-based offline repair (primary path on a physical machine without a pre-existing disk image). Boot the recovery USB you created in Step 0A. From WinRE → Troubleshoot → Advanced options → Command Prompt, try the following in order, rebooting between each step to see if the host comes back:

    1.1. Identify the system drive's letter under WinRE. WinRE re-letters drives, so C: from the running OS may be D: or E: here. Run diskpart, list volume, find the volume with the Windows installation, note its letter, then exit. The examples below use C: — replace with your actual letter.

    1.2. Revert any uncommitted Setup transaction:

    dism /image:C:\ /cleanup-image /revertpendingactions

    This undoes a pending driver install or servicing operation that didn't finish before the failed reboot. Always try this first — it is the cheapest fix and resolves a meaningful fraction of cases where the install transaction itself was the problem.

    1.3. Remove the published OEM drivers this repository's scripts added:

    dism /image:C:\ /get-drivers /format:table

    Identify the oem<NN>.inf entries published by this repository (the Provider column will show the self-signed cert Subject CN, e.g. AMD Chipset Driver Self-Sign (WS2019 Lab, At Own Risk)). For each, remove it:

    dism /image:C:\ /remove-driver /driver:oem<NN>.inf

    This removes the offending driver-store entries without booting the broken OS. After all repository-published OEM drivers are removed, reboot.

    1.4. If upgrading from r69 or earlier, also remove any leftover WDAC SPF policy. r70 deleted the orchestrator and the four driver scripts no longer deploy a host-wide SPF policy. However, hosts that previously ran Chipset / Graphics / BthPan Install under r69 or earlier may still have a C:\Windows\System32\CodeIntegrity\SiPolicy.p7b deployed by the now-removed orchestrator. If WinRE recovery is required on such a host, removing that file from WinRE is the equivalent of the orchestrator's -Action Uninstall:

    del C:\Windows\System32\CodeIntegrity\SiPolicy.p7b

    If BitLocker is enabled on C:, you will be prompted for your recovery key on the next boot — this is why Step 0B is mandatory. Hosts that have only ever run r70-or-later releases of this repository will not have this file, and this step is a no-op for them.

    1.5. Startup Repair as a final WinRE-side attempt: Troubleshoot → Advanced options → Startup Repair. Microsoft's automatic repair handles a small set of boot-loader-only corruptions that the above commands don't address.

  2. Roll back to a pre-Install full disk image (if you took one in Step 0C). On a physical machine this means booting the imaging tool's rescue media (Macrium / Clonezilla / etc.) and restoring the C: image to the original drive. Expect 20–60 minutes depending on drive size. This is the fastest path to a known-good state IF you have an image, but most physical-machine operators will not.

  3. Pull the disk and read offline from a working machine. If the recovery USB doesn't boot for some reason (UEFI Secure Boot policy on the failed host rejecting it, etc.), the next step is to physically remove the drive, attach it to a working machine via USB-to-NVMe / SATA adapter, and run dism /image: and del commands from that second machine. This is slower than option 1 but covers cases where the failed host won't boot any external media.

  4. OS reinstall (last resort). When options 1–3 fail or are not practical (no recovery USB, no spare machine, no disk image), reinstall from your Step 0D media. This is the explicitly-supported recovery path of last resort for this repository, and is the reason the disclaimer emphasises "a physical machine you are prepared to wipe and reinstall".

The repository does not ship a recovery script that runs from inside a broken OS, because by the nature of the failure mode the OS is no longer running. The protections we do ship are entirely pre-emptive: the Step 0 checklist above, aggressive -Action PrepareVerify dry-run output, V05/V06 hardware-impact analysis, and the strict reboot-between-scripts sequencing.

Selective phase execution

# Just regenerate the patched INFs and catalogs without re-downloading
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1 -Action Prepare -OnlyPhases P05,P06,P08,P09

# Run only the cert-trust phase
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1 -Action Install -OnlyPhases I01

# Run only the BthPan Phantom-OK readiness analysis (no system change)
.\Deploy-MSBthPanInboxOnWindowsServer.ps1 -OnlyPhases V06

# List all phases the script knows about
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1 -Action ListPhases

BthPan-specific quick start

The BthPan script is the simplest of the four to run because the driver source is the host's own DriverStore — no network download, no AMD account, no EULA-gated ZIP.

Step 1 — confirm the Bluetooth host controller is bound

The BthPan script handles only BTH\MS_BTHPAN (the Personal Area Network child device exposed after the Bluetooth host controller is bound). The host controller itself is out of scope.

# Confirm the host controller is showing Status=OK (NOT "Unknown device").
Get-PnpDevice -Class Bluetooth -ErrorAction SilentlyContinue |
    Select-Object FriendlyName, Status, InstanceId

# If the host controller (e.g. Intel AX210, Realtek RTL8852, MediaTek MT7921)
# is "Unknown device", install its vendor driver first. The bthpan script
# does NOT install host-controller drivers.

Step 2 — diagnose the current state (no system change)

.\Deploy-MSBthPanInboxOnWindowsServer.ps1 -OnlyPhases V06

V06 prints the per-instance classification of every BTH\MS_BTHPAN* device on the host. Three states are possible:

Classification Meaning Recommended next step
Unknown Status=Error (code 28). No driver is bound. Run -Action Install.
Phantom Status=OK, but DriverInfPath=bth.inf, Class=Bluetooth, Service=(empty). bthpan.sys is NOT loaded; PAN networking is broken even though Device Manager looks fine. Run -Action Install. After install, I04 verifies the rebind.
True DriverInfPath=oem*.inf, Class=Net, Service=BthPan. bthpan.sys is loaded; BthPan service is running. No action needed. The host is already at true resolution.

Step 3 — full installation

.\Deploy-MSBthPanInboxOnWindowsServer.ps1 -Action All -CleanWorkRoot

-Action All runs all 21 phases (P00-P09V01-V06I00-I04) in a single command. I03 includes pnputil /scan-devices to force the PnP manager to re-evaluate BTH\MS_BTHPAN so it rebinds from bth.inf (the Phantom proxy match) to the patched oem*.inf (true resolution).

If I04 reports *** TRUE RESOLUTION NOT YET ACHIEVED ***, a reboot is the typical fix; sometimes the PnP rebind only takes effect on next boot. Re-run the same command after reboot — the script's resume-after-reboot logic detects the new state and reports *** TRUE RESOLUTION ACHIEVED ***.

Step 4 — decoration strategy choice (advanced)

# Strategy A (default): NTamd64...3 only (ProductType=3 covers all Server SKUs).
.\Deploy-MSBthPanInboxOnWindowsServer.ps1 -DecorationStrategy A

# Strategy B: also add NTamd64.10.0...14393 / 17763 / 20348 / 26100 explicitly.
# Provides slightly higher PnP-ranking advantage when a future Microsoft inbox
# update adds Server decorations of its own. Requires manual update for any
# new Server SKU build that ships in the future.
.\Deploy-MSBthPanInboxOnWindowsServer.ps1 -DecorationStrategy B

In practice Strategy A is sufficient on all four supported Server builds (14393 / 17763 / 20348 / 26100). Strategy B exists for environments where multiple coexisting bthpan packages compete for the binding slot and per-build entries give a deterministic tie-break.

Step 5 — verify the outcome

# bthpan.sys present?
Test-Path C:\Windows\System32\drivers\bthpan.sys

# BthPan service registered + running?
Get-Service BthPan -ErrorAction SilentlyContinue

# Bluetooth PAN NetAdapter visible?
Get-NetAdapter | Where-Object InterfaceDescription -Match 'Bluetooth.*Personal Area Network'

# Device-level state (Class should be Net, Service should be BthPan):
Get-PnpDevice -InstanceId 'BTH\MS_BTHPAN*' |
    Get-PnpDeviceProperty -KeyName DEVPKEY_Device_Class, DEVPKEY_Device_Service, DEVPKEY_Device_DriverInfPath

NPU-specific quick start

Reminder: this script is experimental. Read Risk classification of the four scripts before continuing.

🆘 r17 (2026-05-23, Q-X1) — NPU refuses Install on legacy Windows Server. Starting in r17, Deploy-AMDNpuDriverOnWindowsServer.ps1 will refuse -Action Install and -Action All on Windows Server 2019 (build 17763) and Windows Server 2016 (build 14393). The AMD NPU driver pipeline has no physical-hardware validation on legacy Server SKUs, and running Install on these hosts would be operating on unvalidated code. Non-destructive actions remain available on WS2019/2016: -Action PrepareVerify (default), -Action Prepare, -Action Verify, -Action Cleanup, -Action ListPhases. If you need NPU on WS2019/2016, open a GitHub issue — the path can be enabled after dedicated physical validation. See SPEC §D.27.

Step 1 — obtain the NPU driver ZIP (one of the four tiers)

The NPU script supports four download tiers in priority order:

Tier Method When to use
1 -InstallerUrl <url> explicit URL You already have a fresh AMD CDN URL (e.g. from an entitlenow.com link captured in a browser session).
2 -AmdAccountUser <email> -AmdAccountPassword <SecureString> -ForceAmdAccountAuth Attempt EULA acceptance flow automatically. ❌ Disabled by default since 2026-05-10 verification found account.amd.com is a JavaScript-driven SPA. Use -ForceAmdAccountAuth to opt in (expected to fail on the current AMD portal). See TESTING.md §3.6 for the full verification report.
3 EULA-gated direct fetch probe Automatic; almost always falls through (AMD requires JS-driven submission).
4 -OfflineZip <path> or sibling NPU_RAI*_WHQL.zip in the script directory Recommended. Manually download the ZIP once, place it next to the script. Reproducible across runs.

For Tier 4, manually download the ZIP from the AMD documentation page:

Step 2 — dry run (no system state modified)

The recommended pattern is -Action PrepareVerify + -OfflineZip. With -OfflineZip, the 4-tier resolution short-circuits at the Tier 4 priority block (line 824 of the script) and your local ZIP is used immediately — no AMD network calls, no form-parsing fragility.

# RECOMMENDED — pipeline soundness check, system state UNCHANGED.
# OfflineZip is taken from the Tier 4 priority block immediately; no AMD network calls.
# On a real NPU host (Ryzen AI 300 / AI Max 300 / 7040 / 8040 series):
.\Deploy-AMDNpuDriverOnWindowsServer.ps1 `
    -Action PrepareVerify `
    -CleanWorkRoot `
    -OfflineZip .\NPU_RAI1.6.1_314_WHQL.zip
# Pipeline-soundness check on a host without an NPU device — same as above plus -AssumeIfMissing.
# When P03 detects no NPU device, the script falls back to the default Strix Point profile
# instead of failing. Useful only for testing the pipeline mechanics; produces 0 device bindings
# and provides no validation of real NPU behaviour.
.\Deploy-AMDNpuDriverOnWindowsServer.ps1 `
    -Action PrepareVerify `
    -CleanWorkRoot `
    -OfflineZip .\NPU_RAI1.6.1_314_WHQL.zip `
    -AssumeIfMissing                            # default Strix Point + RAI 1.7.1
# DISCOURAGED — pipeline check WITHOUT -OfflineZip on a clean machine.
# This command will:
#   Tier 1 (-InstallerUrl)            : skipped (not provided)
#   Tier 4 priority (-OfflineZip)     : skipped (not provided)
#   Tier 2 (AMD account auto-download): skipped (no credentials)
#   Tier 3 (EULA-gated direct probe)  : almost always falls through (HTML form)
#   Tier 4 auto-scan                  : checks script dir, ./cache, workspace, ~/Downloads
# If -CleanWorkRoot has wiped the workspace AND no NPU_RAI*_WHQL.zip is in any of the
# auto-scan locations, P03 will throw "All 4 download tiers exhausted".
.\Deploy-AMDNpuDriverOnWindowsServer.ps1 -Action PrepareVerify -CleanWorkRoot

Step 3 — install (only if you have real NPU hardware AND have read all warnings)

# RECOMMENDED — full install using a manually-downloaded offline ZIP.
.\Deploy-AMDNpuDriverOnWindowsServer.ps1 `
    -Action Install `
    -OfflineZip .\NPU_RAI1.6.1_314_WHQL.zip
# I00 will require you to type "I AGREE" to acknowledge:
#   1) AMD Ryzen AI EULA acceptance
#   2) Ryzen AI Software being officially Windows-11-only
#   3) Kernel-mode driver only (user-mode stack must be installed separately)
#   4) BitLocker recovery keys recorded

After successful installation, the script prints a guidance block reminding you that Ryzen AI Software (Python conda env, OGA, Vitis AI EP) must be installed separately from https://account.amd.com/en/forms/downloads/xef.html?filename=ryzen-ai-lt-1.7.1.exe, and that this user-mode stack is officially supported on Windows 11 build >= 22621.3527 only — not on Windows Server 2025.

Useful NPU-specific switches

The NPU script tracks two independent versioning axes plus a separate compatibility evaluation axis, per AMD's Ryzen AI Software installation documentation:

Axis Parameter Default What it controls
A. NPU kernel-mode driver -NpuDriverPackage latest (= NPU_RAI1.6.1_314) Which NPU driver ZIP package the script targets. AMD currently publishes only two: NPU_RAI1.5_280 (driver 32.0.203.280) and NPU_RAI1.6.1_314 (driver 32.0.203.314). Both cover all NPU codenames (PHX/HPT/STX/STH/KRK). Driver versioning evolves slowly.
B. Ryzen AI Software (user-mode stack) -RyzenAiSoftwareVersion latest (= 1.7.1) Which Ryzen AI Software version is referenced in the post-install guidance (you install the EXE separately). AMD recommends always using the latest for end-user workloads.
C. Compatibility evaluation (automatic) n/a Computed from A + B at P03. Currently AMD documents that all RAI versions require driver ≥ 32.0.203.280, so both 280 and 314 are compatible with RAI 1.5 through 1.7.1.

Switches in column A and B are independent. They do not need to share a version label; e.g. -NpuDriverPackage NPU_RAI1.6.1_314 -RyzenAiSoftwareVersion 1.7.1 is a valid, AMD-supported combination (newer driver + latest RAI Software).

These switches modify behaviour but do not provide a download source by themselves. Always combine them with -OfflineZip, -InstallerUrl, or -AmdAccountUser/-AmdAccountPassword -ForceAmdAccountAuth (Tier 4 / Tier 1 / Tier 2 respectively).

# Force a specific NPU codename (when CPU name detection is ambiguous; e.g. PHX vs HPT).
# Combine with -OfflineZip for predictable behaviour:
.\Deploy-AMDNpuDriverOnWindowsServer.ps1 `
    -Action PrepareVerify `
    -OfflineZip .\NPU_RAI1.6.1_314_WHQL.zip `
    -NpuOverride STX                            # PHX | HPT | STX | KRK

# Pin a specific NPU driver package (axis A). Note: -NpuDriverPackage selects which
# package the script reasons about. Your -OfflineZip must match the same package.
.\Deploy-AMDNpuDriverOnWindowsServer.ps1 `
    -Action Install `
    -OfflineZip .\NPU_RAI1.6.1_314_WHQL.zip `
    -NpuDriverPackage NPU_RAI1.6.1_314          # NPU_RAI1.5_280 | NPU_RAI1.6.1_314 | latest

# Pin a specific Ryzen AI Software version (axis B). Default 'latest' is recommended.
# This affects only the post-install guidance message - the user installs the
# Ryzen AI Software EXE separately via the AMD download page.
.\Deploy-AMDNpuDriverOnWindowsServer.ps1 `
    -Action Install `
    -OfflineZip .\NPU_RAI1.6.1_314_WHQL.zip `
    -RyzenAiSoftwareVersion latest              # 1.5 | 1.6.1 | 1.7 | 1.7.1 | latest

# AMD account auto-download (Tier 2 — DISABLED by default since 2026-05-10 verification.
# Pass -ForceAmdAccountAuth to opt in. Expected to fail on current AMD SPA portal.)
$cred = Get-Credential -UserName 'you@example.com' -Message 'AMD account password'
.\Deploy-AMDNpuDriverOnWindowsServer.ps1 `
    -Action Install `
    -ForceAmdAccountAuth `
    -AmdAccountUser $cred.UserName `
    -AmdAccountPassword $cred.Password

Common pitfall: running -Action Install -NpuOverride STX -NpuDriverPackage NPU_RAI1.6.1_314 without specifying any download source will fall through to Tier 4 auto-scan and silently use whatever NPU_RAI*_WHQL.zip happens to be in ~/Downloads — which may or may not match the package you specified. Always pin the source explicitly.


Pipeline architecture (21 + 1 phases)

The four scripts share a 21-phase pipeline (P00–P09, V01–V06, I00–I04). The BthPan script adds one extra Install-group phase (I05) that recovers from a stuck-driver state without reboot when (and only when) I04 detected one. The 21 shared phases are run by all four scripts; I05 is BthPan-only.

Group ID Name What it does
Prep P00 Initialize OS detection, admin/TLS pre-flight, WS2025-preview-mode banner if Workstation; the NPU script also prints a Ryzen-AI-Software OS-support warning
Prep P01 PrepareWorkspace Create C:\Temp\Workspace_AMD-{Chipset,Graphics,NPU}\ or C:\Temp\Workspace_Microsoft-BthPan\ (auto-creates C:\Temp on demand)
Prep P02 AcquireTools Install 7-Zip, Windows SDK (signtool) and Windows WDK (inf2cat) via winget, fall back to direct EXE
Prep P03 FetchInstaller Detect host AMD platform; resolve the latest installer URL from amd.com (chipset/graphics) or run the 4-tier resolution (NPU); download
Prep P04 ExtractInstaller 7-Zip extraction; the NPU script also handles nested ZIP detection
Prep P05 AnalyzeInfs Inventory every INF, classify by source variant (W11x64 / WTx64 / WT6A_INF / WT64A; for NPU: PHX/HPT vs STX/KRK), and select those in scope for the host OS / NPU
Prep P06 PatchInfs For INFs lacking Server decorations, mirror each Workstation [Manufacturer] entry with ProductType=3; copy already-Server-compatible INFs to the patched folder so they reach the install pipeline
Prep P07 CreateCertificate Self-sign a 4096-bit RSA / SHA-384 code-signing cert (5-year validity), exported as PFX and CER
Prep P08 GenerateCatalogs inf2cat /os:Server2025_X64 for each patched INF folder
Prep P09 SignCatalogs signtool sign /fd SHA384 /td SHA384 /tr <timestamp-url> on every catalog
Verify V01 VerifyArtifacts Confirm cert + patched INFs + catalogs all exist
Verify V02 VerifyCertificate Decode the PFX, check EKU, validity, key length
Verify V03 VerifyCatalogs signtool verify /pa (expected to fail until I01 trusts the cert)
Verify V04 VerifyInfs Re-parse patched INFs and confirm ProductType=3 decoration coverage
Verify V05 DryRunInstall Simulate I01-I03 against Win32_PnPSignedDriver; predict every install / skip / upgrade decision; produce the install plan
Verify V06 HardwareImpactAnalysis Enumerate AMD hardware on this host, compare AS-IS drivers against TO-BE patched drivers, classify upgrade risk (HIGH / MEDIUM / LOW); the NPU script also reminds the operator about the Ryzen AI Software user-mode stack
Inst I00 PreInstallReview Print the V06 risk summary; require operator acknowledgement (NPU script: also requires explicit I AGREE for the Ryzen AI EULA)
Inst I01 TrustCertificate Import CER into LocalMachine\Root + LocalMachine\TrustedPublisher
Inst I02 AuthorizeDriverSigning Build + deploy the WDAC supplemental policy referencing this cert — only when -WdacBasePolicyGuid is supplied; no default base policy is assumed and the phase refuses the supplemental deployment otherwise (SPEC D.58.8). Fall back to bcdedit /set testsigning on only if -UseTestSigning is passed. Activation follows the OS activation plan (SPEC D.58.9): inbox CiTool.exe on Windows Server 2025 / Windows 11 22H2+; the downloadable RefreshPolicy.exe or the WMI/CIM PS_UpdateAndCompareCIPolicy bridge on WS2022; on WS2016/WS2019 the supplemental path is refused (single-policy format). BCDEdit testsigning runs only with an explicit -UseTestSigning (Mode T, lab host only).
Inst I03 InstallDrivers pnputil /add-driver <patched.inf> /install for every in-scope INF
Inst I04 PostInstallVerification Re-enumerate AMD hardware, confirm [C] Self-signed driver bound to each target device; the NPU script also displays Ryzen AI Software user-mode stack installation guidance. For the BthPan script, this phase uses language-independent identifiers (DriverFileName, ComponentID, PnPDeviceID) and is therefore correct on Japanese, Chinese, German, etc. SKUs — see SPEC §D.19.
Inst I05 ForceRebind (BthPan only) When (and only when) I04 OverallResult = PartialOrPhantom, escalate through Restart-PnpDeviceDisable/Enable-PnpDevicepnputil /remove-device /scan-devicesStop/Start-Service BthPan to recover the driver binding without reboot. Capabilities are auto-detected on WS2016 / WS2019 / WS2022 / WS2025 and missing cmdlets are gracefully skipped — see SPEC §D.22. On success, I04 OverallResult is promoted to TrueResolution and the pending-reboot marker is cleared.

Parameters (per script)

All four scripts share a common parameter contract for -Action, -OnlyPhases, -CleanWorkRoot, -AllowWorkstationInstall, -UseTestSigning, -WorkRoot, and -PfxPassword. The chipset and graphics scripts share additional source-discovery and help switches; the NPU script adds a 4-tier installer source resolution and platform override block; the BthPan script adds a single -DecorationStrategy A|B switch and otherwise reuses the common contract.

Common parameters (chipset, graphics, NPU, BthPan)

Parameter Default Description
-Action PrepareVerify Prepare / Verify / PrepareVerify / Install / All / Cleanup / ListPhases
-OnlyPhases @() Phase IDs (e.g. P05, P06, P08, P09) or short names (e.g. PatchInfs); overrides -Action
-CleanWorkRoot (off) Delete the workspace directory before starting (forces a fresh download/extract/copy)
-AllowWorkstationInstall (off) Permit Install-phase actions on Workstation OS (Win11). Discouraged — default blocks Install
-UseTestSigning (off) Fall back to bcdedit /set testsigning on instead of WDAC supplemental policy. Discouraged
-WorkRoot per-script Override workspace path (chipset: C:\Temp\Workspace_AMD-Chipset, graphics: C:\Temp\Workspace_AMD-Graphics, NPU: C:\Temp\Workspace_AMD-NPU, BthPan: C:\Temp\Workspace_Microsoft-BthPan). Located under C:\Temp\Workspace_*; the script auto-creates C:\Temp on demand
-LogFile auto-generated Path of the full console transcript captured via Start-Transcript / Stop-Transcript. r91+: when omitted, a transcript is always created automatically under <WorkRoot>\\logs\\<ScriptName>_<Action>_<yyyyMMdd-HHmmss>_<PID>.log, starting before the entry banner so the log contains the banner and the full P00 environment report (survives -CleanWorkRoot via a suspend/wipe/resume flow; no opt-out switch). Pass an explicit path to override the location. The file receives every stream (Output / Host / Error / Warning / Verbose / Debug) as plain text; the interactive console keeps its Write-Host -ForegroundColor decoration intact. Recommended over the legacy ... \|*>&1 \| Tee-Object -FilePath ... idiom, which strips Write-Host coloring
-SkipEvidenceCollection (off — collection runs) r94+ (all four). Evidence collection is ON by default: every run except ListPhases invokes Collect-WindowsServerConfigurationEvidence.ps1 (shipped next to the script) with stage pre before the first phase and stage post as the last step of the run, producing diffable read-only evidence ZIPs next to the script. Specify this switch to skip both collections. Best-effort: collector problems are warnings only and never affect the run. (r93 shipped this as the opt-in -CollectEvidence; r94 inverted the polarity to satisfy the original always-on requirement — PSA6006 forbids switches defaulting to $true.)
-PfxPassword per-script Password for the self-signed PFX. All four sisters: per-run random 32-char CSPRNG when omitted (W4; NPU joined in W7 — audit H-05R closed)
-WdacPolicyGuid per-script (fixed UUID v4) Override the fixed WDAC supplemental policy GUID. Default is per-script (chipset: 503860EA-…, graphics: 85336828-…, NPU: 8B2C4F12-…, BthPan: A6E72D4F-3B98-4C5A-9E1D-7F8B2A4C6E5D). Used for legacy-deploy cleanup or side-by-side multi-instance deploy
-ForceUnsafe (off) r69+ (Chipset/Graphics/BthPan only). Bypass the CRITICAL acknowledgement checklist that I00 PreInstallReview prompts the operator with when conditions C1/C2/C5/C6 fire (display driver replacement on single-display host; BitLocker ON + AMD PSP driver replacement; host hasn't been rebooted in 24+ hours; r71: WHQL co-sign shortfall on Secure-Boot-ON host). Intended for CI/CD automation only; the bypass is logged via Set-DebugStep in the run transcript. Do NOT use in production. See SPEC §D.28 and §D.31.4
-SkipNonCosignedDrivers (off) r71+ (Chipset/Graphics/BthPan only). Skip the non-WHQL-co-signed subset of the install plan. When set, P05 builds the WHQL co-sign analysis and P06 entry trims $Ctx.InfInventory to only the INFs whose .sys files all carry a Microsoft Windows Hardware Compatibility co-signature. Downstream phases (P06 patch, P07 cert, P08 catalog, V03-V06 verify, I03 install) all read the trimmed inventory automatically. r72+: I02 short-circuits when this flag is set and the trimmed plan is fully WHQL co-signed — no WDAC supplemental policy is deployed, no bcdedit testsigning flag is set, no firmware Secure Boot change is required. Use this on hosts that must keep UEFI Secure Boot ENABLED in firmware. Non-WHQL drivers will not be installed; operators who need those devices must accept Path B or leave them unbound. r96/r97: the trim is schema-tolerant and its semantics are corrected — already-Server-compatible (no-patch) INFs are always eligible; only the patch-needing subset requires the WHQL co-sign classification. P05/P06 persist the analysis and the post-trim plan as whql_cosign_analysis.json / whql_cosign_plan.json (SchemaVersion 2, install-scope aggregation, PlanCatalogSignCount) in the workspace root so the split PrepareVerify -> Install workflow sees the plan. I01 is skipped (trust stores untouched) only when the plan contains no catalogs for the pipeline to self-sign — on any normal plan I01 runs, because every plan catalog is regenerated and self-signed for the Server OS target. See SPEC §D.31, §D.31.11 and §D.31.17

Chipset / Graphics-specific parameters

Parameter Default Description
-Help / -h / -? (off) Show formatted usage information and exit
-References (off) Display curated list of Microsoft Learn documentation links and exit
-InstallerUrl '' Explicit URL to the AMD installer EXE — bypasses the URL discovery probe
-AmdLandingUrls per-script default array Landing pages to scrape for installer EXE URL (override only if AMD changes their site structure)
-AmdFallbackUrl per-script default URL Last-resort hard-coded installer URL when landing page scraping fails
-Force (off) Force overwrite of existing workspace files (use with care). Since W8 it does not bypass the Authenticode download gate
-AllowUnverifiedDownload (off) Sole override for the fail-closed download gate — AMD installer only; continues as operator-attested-unverified with a loud warning and a SourceArtifact record. Microsoft/7-Zip downloads are never overridable
-TimestampUrl http://timestamp.digicert.com RFC 3161 timestamp server for signtool sign /tr
-WdacBasePolicyGuid (none) The SupplementsBasePolicyID the WDAC supplemental policy targets. NO DEFAULT — without it the supplemental deployment is refused. Supply the GUID of a base policy you have verified is deployed with rule option 17 (Enabled:Allow Supplemental Policies). SPEC D.58.8

Note: The chipset and graphics scripts do not currently expose -CertValidityYears; the default 5-year validity is hard-coded. Only the NPU script exposes this as a configurable parameter.

NPU-specific parameters

Parameter Default Description
-InstallerUrl (none) Tier 1: explicit URL to the NPU driver ZIP
-OfflineZip (none) Tier 4 priority: path to a pre-downloaded NPU driver ZIP (recommended pattern)
-AmdAccountUser (none) Tier 2: AMD account email for auto-download (BEST-EFFORT — disabled by default)
-AmdAccountPassword (none) Tier 2: AMD account password (SecureString)
-ForceAmdAccountAuth (off) Opt in to Tier 2 form-based auth (expected to fail against current AMD JS-driven SPA portal)
-NpuOverride (none) Force a specific NPU codename: PHX / HPT / STX / KRK
-NpuDriverPackage latest NPU kernel-mode driver package: NPU_RAI1.5_280 / NPU_RAI1.6.1_314 / latest (resolves to NPU_RAI1.6.1_314)
-RyzenAiSoftwareVersion latest Ryzen AI Software (user-mode stack) version recommendation: 1.5 / 1.6.1 / 1.7 / 1.7.1 / latest
-AssumeIfMissing (off) If NPU not detected, proceed using default profile (Strix Point + NPU driver 32.0.203.314 + RAI Software latest)
-CertValidityYears 5 Self-signed cert validity period in years (NPU script only)

Note on NPU driver vs Ryzen AI Software versioning: per AMD documentation at https://ryzenai.docs.amd.com/en/latest/inst.html, NPU kernel driver and Ryzen AI Software are versioned independently. -NpuDriverPackage and -RyzenAiSoftwareVersion are therefore independent switches; you can combine any driver with any software (e.g. -NpuDriverPackage NPU_RAI1.6.1_314 -RyzenAiSoftwareVersion 1.7.1).

BthPan-specific parameters

Parameter Default Description
-Help / -h / -? (off) Show formatted usage information and exit
-References (off) Display curated list of Microsoft Learn documentation links and exit
-Force (off) Force overwrite of existing workspace files (bypass cached Phase markers)
-TimestampUrl http://timestamp.digicert.com RFC 3161 timestamp server for signtool sign /tr
-DecorationStrategy A A (default): add only NTamd64...3 (ProductType=3 covers all Server SKUs). Simple, durable against future Server SKUs.
B: also add NTamd64.10.0...14393 / 17763 / 20348 / 26100 per-build entries. Useful when explicit PnP-ranking tie-break is required, but needs manual update for any new Server SKU build.
-WdacBasePolicyGuid (none) The SupplementsBasePolicyID the WDAC supplemental policy targets. NO DEFAULT — without it the supplemental deployment is refused (SPEC D.58.8)

Note: the BthPan script intentionally does NOT expose -InstallerUrl / -AmdLandingUrls / -AmdFallbackUrl / -OfflineZip parameters, because there is no remote installer to fetch — the driver is the host's own bthpan.inf from C:\Windows\System32\DriverStore\FileRepository\bthpan.inf_amd64_*.


Output files

Each script writes the following artifacts under its workspace (C:\Temp\Workspace_AMD-{Chipset,Graphics,NPU}\ or C:\Temp\Workspace_Microsoft-BthPan\):

Path (relative to workspace) Content
download\<installer> AMD installer EXE (chipset/graphics) or NPU driver ZIP (NPU); empty for BthPan (no remote source)
extracted\ Unpacked installer contents (original INFs, SYS, DLL, CAT files); for BthPan: extracted\bthpan\ with the DriverStore copy
patched\<inf> Patched INF files with ProductType=3 decoration mirrors (BthPan: patched\bthpan\bthpan.inf)
patched\<cat> Regenerated catalog files (inf2cat /os:Server2025_X64,... output)
cert\AMD-Chipset-Driver-CodeSign.pfx (chipset) / cert\AMD-Graphics-Driver-CodeSign.pfx (graphics) / cert\AMD-NPU-Driver-CodeSign.pfx (NPU) / cert\MS-BthPan-Driver-CodeSign.pfx (BthPan) Self-signed code-signing certificate (PFX format)
cert\AMD-Chipset-Driver-CodeSign.cer (chipset) / cert\AMD-Graphics-Driver-CodeSign.cer (graphics) / cert\AMD-NPU-Driver-CodeSign.cer (NPU) / cert\MS-BthPan-Driver-CodeSign.cer (BthPan) Public certificate (CER format) for trust-store import
cert\AmdSuppPolicyId.txt (chipset/graphics) / cert\MsBthPanSuppPolicyId.txt (BthPan) Marker file recording the WDAC supplemental PolicyId for later cleanup
cert\WDAC-Supplemental-NPU.xml / .cip (NPU) WDAC supplemental Code Integrity policy (XML source + binary deployed to C:\Windows\System32\CodeIntegrity\CiPolicies\Active\)
cert\MsBthPanSelfSignedSupplementalPolicy.xml / .cip (BthPan) WDAC supplemental Code Integrity policy for BthPan (XML source + binary deployed to C:\Windows\System32\CodeIntegrity\CiPolicies\Active\). Uses the BthPan-specific GUID A6E72D4F-3B98-4C5A-9E1D-7F8B2A4C6E5D.
inf_inventory.csv Per-INF inventory from P05 (file name, provider, class, HWID count, decoration status, etc.). BthPan: single-row CSV
inf_inventory_report.txt Human-readable summary of P05 INF analysis (includes UEFI Secure Boot baseline appendix)
logs\inf2cat_bthpan.log (BthPan) inf2cat verbose log; useful for diagnosing catalog generation failures
logs\pnputil_bthpan.log (BthPan) pnputil add-driver/install output
logs\pnputil_scan-devices.log (BthPan) pnputil /scan-devices output (I03 forces PnP rebind)
logs\<ScriptName>_<Action>_<yyyyMMdd-HHmmss>_<PID>.log Automatic run transcript (r91+); written for every run unless an explicit -LogFile overrides the path
logs\amd-landing-probe-*.html (chipset) Probe-miss evidence: raw AMD landing pages preserved when URL discovery returns 0 hits (r91+; SPEC D.37)
logs\run-artifact-archive-plan.txt Marker recording the planned run-artifact ZIP name (r92+; the ZIP carries this marker so it is self-identifying)
secureboot_ms_sample\*.json UEFI Secure Boot baseline evidence from the Microsoft sample script

CSV column conventions

inf_inventory.csv follows these conventions across all four scripts:

Column Type Meaning
FileName string INF filename (e.g. kipudrv.inf, bthpan.inf)
FullPath string Absolute path inside the workspace
Provider string INF [Version] Provider field (e.g. AdvancedMicroDevicesInc., Microsoft)
DriverVer string INF DriverVer line (e.g. 07/08/2025,32.0.203.314)
Class string Device class (e.g. Computer, Display, System, Net)
HwidCount int Total Hardware IDs referenced in the INF
MatchesTargetNpu bool (NPU only) INF references the target NPU PCI HWID pattern
MatchedHwidCount int Number of HWIDs in this INF that match the target device
HasServerDecoration bool INF already has ProductType=3 decoration (no patching needed)
NeedsPatch bool INF has Workstation-only decorations and requires ProductType=3 mirroring
SelectedForPipeline bool INF passes the script's filter and enters the patch/sign pipeline

UEFI Secure Boot baseline

All four scripts (chipset / graphics / NPU / BthPan) capture the host's UEFI Secure Boot certificate rollout state once at P00 and reuse the snapshot throughout the pipeline. This is informational only — the OS-layer self-signing trust chain that these scripts operate on is independent of the firmware-layer UEFI Secure Boot certificate database. Operators who run multiple sister scripts on the same host see consistent baseline reporting and can correlate UEFI cert-rollout state with driver-install outcomes.

Windows Driver Policy on Windows Server 2025+

Starting with the April 2026 servicing wave, Windows Server 2025 and later carry a Microsoft-managed Windows Driver Policy that removes default trust for legacy cross-signed kernel drivers. It is a separate layer from anything this project deploys (SPEC D.58.6). It ships with identifiable policy GUIDs (Audit {784C4414-79F4-4C32-A6A5-F0FB42A51D0D}, Enforce {8F9CB695-5D48-48D6-A329-7202B44607E3}) under the EFI system partition at \EFI\Microsoft\Boot\CiPolicies\Active\, evaluates a host for 250 hours of real use and at least 2 boot sessions on Server before enforcing, and resets both counters when a would-be-blocked driver loads during evaluation. These scripts do not disable it and never will (acceptance gate G-04): Microsoft's own Custom Kernel Signers procedure treats the policy as strong enough to require explicit disablement, and a deployment tool that silently weakens a Microsoft security baseline to raise its own success rate is doing the operator harm. Detection and evidence for this layer are collected by the evidence collector as of c11 (windows-driver-policy.json; audit H-06). Note also that deleting a deployed signed CI policy without a valid replacement makes Windows fail to boot — the WinRE del recovery documented in this README applies to this project's unsigned artefacts only (SPEC D.30.6, D.58.6).

What gets captured

The snapshot combines two sources:

  1. Embedded inventory — direct reads via Confirm-SecureBootUEFI, Get-SecureBootUEFI db/kek for the five canonical certificates (Windows UEFI CA 2023, Microsoft KEK 2K CA 2023, Microsoft UEFI CA 2011, Microsoft UEFI CA 2023, Microsoft Option ROM UEFI CA 2023), HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot{,\Servicing,\Servicing\DeviceAttributes} registry keys, and the \Microsoft\Windows\PI\Secure-Boot-Update scheduled task state (via Get-ScheduledTask for locale-independent results on ja-JP hosts).

  2. Microsoft sample script — when present at %SystemRoot%\SecureBoot\ExampleRolloutScripts\Detect-SecureBootCertUpdateStatus.ps1 (delivered by KB5089549 on Windows 11, KB5087544 / KB5088863 on Windows 10, and the WS2025 equivalent starting 2026-05-12), the script is launched as a child PowerShell to fetch Microsoft's confidence bucket assessment. A stdout-JSON fallback handles the MS script's input-validator bug that rejects any -OutputPath containing : (every absolute Windows path).

Where it's displayed

Phase Form Purpose
P00 one-line compact: Secure Boot baseline: enabled=true UEFI-CA-2023=NotStarted health=Warning [MS-sample=ok] Immediate operator awareness
P05 full text appendix at the bottom of inf_inventory_report.txt Change-management documentation
V05 one-line compact [Dry-Run UEFI Baseline] block Pre-commit sanity readout
V06 full multi-section breakdown (Section 4 for chipset/graphics, Section 5 for NPU) Detailed forensics view
I02 pre-check + cross-reference with planned WDAC / testsigning path Operator confirmation before touching OS-layer signing

The same in-memory snapshot is reused across all five sites; the MS sample script is invoked at most once per run.

Health classification

  • Healthy — Secure Boot ON, UEFI CA 2023 rollout Updated (or not applicable), no rollout errors.
  • Warning — Secure Boot ON but rollout is in flight (NotStarted / Started / Pending), scheduled task is disabled, or MS sample reports rollout-event diagnostics.
  • Critical — Secure Boot OFF (planned WDAC path expects ON), or a non-zero UEFICA2023Error indicates a stuck rollout.

I02 surfaces the classification but never blocks on it (the two trust layers are independent). On Critical or Warning the operator sees a yellow advisory and decides whether to proceed.

Diagnostic files

When the MS sample script is invoked, the following files are written under <WorkRoot>\secureboot_ms_sample\:

detect_stdout.log                  - Raw captured stdout (Write-Host + JSON)
detect_stdout_extracted.json       - Parsed JSON object (BucketId, Confidence, Event1801..1803 counts)

These are retained as part of the workspace artefact set and survive subsequent runs unless -CleanWorkRoot is passed.


Console output format

Every line written by the scripts follows a structured, time-stamped format that is identical across all four scripts (chipset, graphics, NPU, BthPan). This is intentional — operators reading logs from mixed runs see the same vocabulary and visual layout.

Marker semantics

Marker Colour Semantic Example
[*] Cyan Step [*] Acquiring signtool, inf2cat, and 7-Zip
[+] Green Ok [+] Cert thumbprint: A1B2C3D4...
[!] Yellow Warn [!] Tier 2 (AMD account auto-download) is disabled by default
[X] Red Fail [X] Top-level error: AMD NPU not detected
[~] DarkGray Skip [~] Inventory CSV: C:\Temp\Workspace_AMD-NPU\inf_inventory.csv

Continuation lines that sit inside a section-banner table (PowerShell environment dump, OS profile, Secure Boot baseline, INF inventory rows, V05 / V06 / I00 sub-blocks) are rendered via the Write-Detail helper, which emits a 4-space-indented line with no timestamp or marker prefix. This is the single sanctioned exception to the "every line has a marker" rule. Operators reading raw logs should treat any 4-space-indented line as visually subordinate to the most recent marker line above it. (See SPEC §A.5.)

Sample output (NPU script, P00 → P03)

========================================================================
 Deploy-AMDNpuDriverOnWindowsServer
 Version: npu-<yyyy.MM.dd>-r<NN>  [<short-kebab-tag>]  SHA256: <12-hex-chars>
 Action : PrepareVerify
 Repo   : https://github.com/usui-tk/Deploy-Drivers-For-WindowsServer
========================================================================

========================================================================
 PHASE P00 - Initialize                 (Prep  )  start: 14:23:05
 script: npu-<yyyy.MM.dd>-r<NN>/<hash12>
========================================================================
[14:23:05]            [*] Running environment and sanity checks
[14:23:05]            [+] Administrator privileges confirmed.
[14:23:05]            [~] TLS protocols enabled: Tls, Tls11, Tls12, Tls13
[14:23:06] [+0.42s]   [+] OS detected     : Microsoft Windows Server 2025 (build 26100)
[14:23:06] [+0.42s]   [~] Profile applied : WS2025
[14:23:06] [+0.42s]   [~] inf2cat /os: switch : Server2025_X64
 PHASE P00 -> DONE     elapsed: 0.45s

========================================================================
 PHASE P03 - FetchInstaller             (Prep  )  start: 14:23:12
========================================================================
[14:23:12]            [*] Detecting NPU platform and resolving installer source (4-tier fallback)
[14:23:12] [+0.18s]   [+] NPU codename         : Strix Point / Strix Halo
[14:23:12] [+0.18s]   [+] NPU short name       : STX
[14:23:12] [+0.18s]   [+] Hardware ID          : PCI\VEN_1022&DEV_17F0&REV_00
[14:23:12] [+0.18s]   [+] NPU driver package   : NPU_RAI1.6.1_314
[14:23:12] [+0.18s]   [+] NPU driver build     : 32.0.203.314
 PHASE P03 -> DONE     elapsed: 1.23s

The phase header banner (= × 72, Magenta) is emitted by the dispatcher; phase functions never print their own banner. The [+X.XXs] elapsed-tag is reset at each phase entry so it tracks time inside the current phase, not total runtime.

Since r92 the RUN SUMMARY ends with an explicit install-readiness verdict (see SPEC D.38 for the field analysis that motivated it):

 Note: [!] lines above are informational / expected-condition notices by
       design (e.g. a baseline check on the unpatched source INF, a
       documented tool fallback, a certificate not yet trusted before
       I01, or a device absent on this host). A real failure marks its
       phase as failed in the timing table.
 Install readiness : READY - no failed phases.

Run log capture (-LogFile)

r91+: every run is transcribed automatically. When -LogFile is omitted (the default), all four scripts auto-generate a transcript at

<WorkRoot>\logs\<ScriptName>_<Action>_<yyyyMMdd-HHmmss>_<PID>.log

and capture the full console transcript via Start-Transcript / Stop-Transcript. The transcript starts before the entry banner, so the captured file contains the banner and the complete P00 execution-environment report. With -CleanWorkRoot, the in-WorkRoot transcript survives the P01 wipe through a suspend/wipe/resume flow: it is stopped and stashed outside the workspace immediately before the wipe, moved back once the directories are recreated, and re-opened with -Append — one continuous file covers the whole run while the wipe itself remains a plain full-tree delete. There is deliberately no opt-out switch (matching the logging policy of the central Update-WindowsServerIso.ps1 project: transcripts are always captured).

Pass an explicit -LogFile <path> to override the location:

# Explicit override: color is preserved in the console, the file gets every stream as plain text
$ts  = Get-Date -Format 'yyyyMMdd-HHmmss'
$log = "C:\Temp\amd-chipset_PrepareVerify_$ts.log"
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1 -Action PrepareVerify -CleanWorkRoot -LogFile $log

Key properties:

  • Console keeps its Write-Host -ForegroundColor decoration intact — unlike the legacy *>&1 | Tee-Object -FilePath … idiom, which strips Write-Host coloring on the way through the pipeline.
  • File receives every stream (Output / Host / Error / Warning / Verbose / Debug) as plain UTF-8 text.
  • Parent directory auto-created on demand (e.g. C:\Temp\ is created if missing).
  • Append mode (-Append -Force) — concurrent re-runs accumulate rather than truncate.
  • Idempotent cleanupStop-Transcript is invoked from the top-level finally block and from a PowerShell.Exiting engine event handler as a fallback.
  • Operator-specified path inside -WorkRoot + -CleanWorkRoot — the pre-existing relocation guard still applies to explicit -LogFile paths (the transcript is moved next to the script so the wipe cannot delete it); only auto-generated transcripts use the in-WorkRoot suspend/wipe/resume flow.

Recommended filename convention when overriding with an explicit -LogFile:

C:\Temp\<scripttag>_<Action>_<yyyyMMdd-HHmmss>.log

Examples:

Script Suggested filename
Chipset C:\Temp\amd-chipset_PrepareVerify_20260517-143022.log
Graphics C:\Temp\amd-graphics_Install_20260517-143022.log
NPU C:\Temp\amd-npu_All_20260517-143022.log
BthPan C:\Temp\ms-bthpan_PrepareVerify_20260517-143022.log

Legacy fallback (Tee-Object)

The legacy *>&1 | Tee-Object idiom is still supported and may be preferable when the log file needs to be piped further into another tool. Note that Write-Host coloring is stripped in this mode (PowerShell's pipeline does not propagate the host stream's color information):

.\Deploy-AMDChipsetDriverOnWindowsServer.ps1 -Action Install *>&1 |
    Tee-Object -FilePath "C:\Temp\amd-chipset_Install_$(Get-Date -Format 'yyyyMMdd-HHmmss').log"

If you redirect output to a file (whether via -LogFile or Tee-Object) on a ja-JP host with the default code page (932 / Shift-JIS), set your file encoding explicitly to UTF-8 to avoid double-encoding of Japanese strings — the scripts call Set-Utf8PipelineEncoding in P00 to enforce UTF-8 for [Console]::OutputEncoding, but consumers of the captured file (text editors, Get-Content, etc.) may still need to be told the file is UTF-8.


Console QuickEdit guard, readiness verdict, and run-artifact archive (r92+)

Three field-driven hardening additions apply to all four scripts:

  • Console QuickEdit guard. Windows Server consoles default to QuickEdit mode, where an accidental click-drag selects text and freezes every console write — the script appears to hang mid-phase (an 18m37s freeze was measured in the field; see SPEC D.38). In mark mode Ctrl-C is copy, not break: it releases the freeze and the run simply continues. The scripts now clear ENABLE_QUICK_EDIT_MODE for the duration of the run and restore the original console mode on exit (ConsoleHost only; fully error-contained; no switch).
  • Install-readiness verdict. The RUN SUMMARY now ends with an explicit Install readiness : READY - no failed phases. / REVIEW REQUIRED - failed: <ids> line derived from per-phase statuses, plus a note that [!] lines are informational / expected-condition notices by design (e.g. baseline checks on the unpatched source INF, documented tool fallbacks, untrusted-root before I01, an absent device). A real failure marks its phase as failed in the timing table.
  • Run-artifact archive. After the summary and after the transcript closes, each run bundles logs\, patched\, cert\ (public material only), secureboot_ms_sample\ and inf_inventory.csv into <ScriptName>_<Action>_run-artifacts_<yyyyMMdd-HHmmss>_<PID>.zip and copies the zip next to the script, so one file can be handed over for analysis. *.pfx private keys are never included; the bulk download\ / extracted\ trees and any file over 50 MB are also excluded. If the script directory is not writable the zip falls back to the WorkRoot root (then %TEMP%). A logs\run-artifact-archive-plan.txt marker records the planned zip name inside the archive itself. On Cleanup runs (workspace already wiped) the archive is skipped.

Configuration evidence collector (r93+)

Collect-WindowsServerConfigurationEvidence.ps1 is a standalone, read-only companion script that captures the Windows Server configuration areas the four deploy scripts operate on, as a timestamped evidence directory + ZIP with a color-coded PASS / FAIL / REVIEW / INFO assessment report (exit codes: 0 = all PASS/INFO, 2 = any FAIL/REVIEW, 1 = fatal error). It is modelled on the iso-project post-install collector.

Collected areas: OS identity (build/UBR), pending-reboot state (advisory vs blocking), PnP inventory incl. problem devices and the AMD/BthPan target families, driver store (pnputil /enum-drivers + Win32_PnPSignedDriver), project self-sign certificates in Root / TrustedPublisher (public properties only — private keys are never read), boot security (Secure Boot, UEFI CA 2023 servicing state, testsigning/nointegritychecks, HVCI, WDAC SiPolicy.p7b, CiTool -lp), recent CodeIntegrity events, setupapi logs (50 MB cap; -SkipSetupApiLog to opt out), the repository script inventory (versions + SHA-256) and a WorkRoot / run-artifact inventory (names only).

Run it standalone at any time:

.\Collect-WindowsServerConfigurationEvidence.ps1

Since r94 the deploy scripts take a pre/post evidence pair automatically on every run (ListPhases excepted) — stage pre runs before the first phase, stage post runs as the very last step after the run-artifact archive, and the stage + invoking script are embedded in the ZIP names so the pair can be diffed. Specify -SkipEvidenceCollection to opt out of both collections (r93 briefly shipped this as the opt-in -CollectEvidence; r94 inverted the polarity):

.\Deploy-AMDChipsetDriverOnWindowsServer.ps1 -Action PrepareVerify -CleanWorkRoot                         # evidence pair taken automatically
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1 -Action PrepareVerify -CleanWorkRoot -SkipEvidenceCollection # opt out

Collector problems (missing file, nonzero exit, error) are reported as warnings and never affect the deployment run. -OutputRoot accepts only the script directory (default) or C:\Temp.

System requirements

  • CPU: For AMD scripts: AMD Ryzen 4000 series or newer (the script's Get-AmdChipsetPlatform heuristic recognises 4000 → AI 300, AI Max 300; older silicon may run but is untested). For the NPU script: Ryzen 7040 / 8040 / AI 300 / AI Max 300 / AI 200 series with an integrated NPU. For the BthPan script: any CPU; the prerequisite is a bound Bluetooth host controller (vendor-agnostic — Intel AX2xx, Realtek RTL88xx, MediaTek MT79xx, Broadcom BCM43xx all qualify).
  • OS: Windows Server 2025 (build 26100) is the production target. Windows 11 24H2 (build 26100) is supported as a preview host (see TESTING.md). Windows Server 2016 / 2019 / 2022 are recognised by the OS profile matrix and inf2cat will pick a corresponding /os: switch (e.g. Server2016_X64, ServerRS5_X64, ServerFE_X64). The BthPan script's P08 explicitly targets all four (Server2025_X64,ServerFE_X64,ServerRS5_X64,Server2016_X64) in a single inf2cat invocation, so one signed catalog covers all Server SKUs.
  • PowerShell: 5.1 (Windows PowerShell Desktop) or 7.x (PowerShell Core). The script's Show-PowerShellEnvironment phase prints the compatibility matrix it sees.
  • Disk: ~5 GB on the workspace volume (~7 GB if you also run the NPU script). BthPan workspace is small (<10 MB — single INF/SYS/CAT).
  • Network: outbound HTTPS to *.amd.com, download.microsoft.com, go.microsoft.com, aka.ms (winget), timestamp.digicert.com (signing timestamp), and (for the NPU script with Tier 2 download) account.amd.com and *.entitlenow.com. The BthPan script needs network access only for timestamp signing (timestamp.digicert.com); no AMD or Microsoft download endpoints are contacted.
  • Privileges: Administrator on the local machine. No domain rights are required.
  • BthPan-specific: a Bluetooth host controller bound and showing Status=OK in Device Manager (the script's V05 / V06 explicitly checks this before running Install). Without a host controller, the patched bthpan driver is still staged in the driver store but cannot bind to any device.

Self-signed certificate: expiry, renewal, and revocation

The certificate generated in P07 is the trust anchor for every patched driver this pipeline installs. It deserves its own section.

Certificate properties

  • Subject:
    • CN=AMD Chipset Driver Self-Sign (WS2025 Lab, At Own Risk) (chipset)
    • CN=AMD Graphics Driver Self-Sign (WS2025 Lab, At Own Risk) (graphics)
    • CN=AMD NPU Driver Self-Sign (WS2025 Lab, At Own Risk) (NPU)
    • CN=Microsoft BthPan Driver Self-Sign (<OsCode> Lab, At Own Risk) (BthPan; <OsCode> is the host OS short name, e.g. WS2025)
  • Key: RSA 4096-bit on WS2019+ / Win11+, RSA 2048-bit on WS2016. SHA-384 signature algorithm on WS2025, SHA-256 on WS2016/2019/2022.
  • EKU: Code Signing (1.3.6.1.5.5.7.3.3).
  • Validity: 5 years from the day P07 ran (WS2019+); 3 years on WS2016. Hard-coded in the script.
  • Storage: PFX in C:\Temp\Workspace_AMD-{Chipset,Graphics,NPU}\cert\ or C:\Temp\Workspace_Microsoft-BthPan\cert\. On all four sisters the PFX password is a per-run random 32-char CSPRNG value when -PfxPassword is omitted (W4; NPU since W7); the exported PFX is ACL-restricted to Administrators+SYSTEM and deleted after Install (the certificate stays in the store; P07 regenerates on demand). Since W7 the NPU script carries the same contract (audit H-05R closed); NPU has no phase-marker cache, so P07 regenerates the certificate on every signing run and the deletion happens in the post-Install block. An earlier revision of this document claimed the PFX was not password-protected, which contradicted the code and is corrected here (audit L-01).
  • Trust anchor for: every .cat file under patched\, the WDAC supplemental policy, and (via I01) LocalMachine\Root + LocalMachine\TrustedPublisher.

What happens at year 5

After the certificate expires:

  • The catalog signatures embedded in .cat files remain valid for files installed before expiry, because Windows checks the signing timestamp (which proves the signature was made while the cert was valid) — not the cert's current validity at boot. This is identical to how every WHQL-signed driver works long after the AMD / Microsoft signing cert has rotated.
  • However, adding new patched drivers with the expired cert via pnputil /add-driver will fail.
  • Re-running this script after expiry is the recovery path. It generates a new cert (different thumbprint, same subject), re-signs the catalogs, and re-imports the new cert. Existing installed drivers are untouched and continue to work.

Renewal procedure (every 5 years, or sooner if compromised)

# 1. Roll the cert and re-sign everything
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1  -Action Prepare -OnlyPhases P07,P08,P09
.\Deploy-AMDGraphicsDriverOnWindowsServer.ps1 -Action Prepare -OnlyPhases P07,P08,P09
.\Deploy-AMDNpuDriverOnWindowsServer.ps1      -Action Prepare -OnlyPhases P07,P08,P09

# 2. Trust the new cert (the old one stays trusted until you remove it)
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1  -Action Install -OnlyPhases I01,I02
.\Deploy-AMDGraphicsDriverOnWindowsServer.ps1 -Action Install -OnlyPhases I01,I02
.\Deploy-AMDNpuDriverOnWindowsServer.ps1      -Action Install -OnlyPhases I01,I02

# 3. Add the freshly-signed drivers to the store (binds existing devices to the new sig)
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1  -Action Install -OnlyPhases I03
.\Deploy-AMDGraphicsDriverOnWindowsServer.ps1 -Action Install -OnlyPhases I03
.\Deploy-AMDNpuDriverOnWindowsServer.ps1      -Action Install -OnlyPhases I03

# 4. Optionally remove the old cert
$old = 'OLD-THUMBPRINT-FROM-PREVIOUS-RUN'
Get-ChildItem 'Cert:\LocalMachine\Root', 'Cert:\LocalMachine\TrustedPublisher' |
  Where-Object Thumbprint -EQ $old | Remove-Item

Revoking the cert

If you suspect the PFX has leaked, immediately:

# 1. Cleanup — removes cert from trust stores, deletes WDAC policy, removes drivers
.\Deploy-AMDChipsetDriverOnWindowsServer.ps1  -Action Cleanup
.\Deploy-AMDGraphicsDriverOnWindowsServer.ps1 -Action Cleanup
.\Deploy-AMDNpuDriverOnWindowsServer.ps1      -Action Cleanup

# 2. Reboot to ensure WDAC policy unload (the script attempts a CiTool --refresh, but a
#    reboot guarantees no residual signing-authority is in the kernel)
Restart-Computer

After reboot, re-run the full pipeline to generate a new cert.

Why 5 years? Why self-signed?

  • 5 years matches the upper bound for Microsoft's own kernel-mode signing certs (rotated every 1-3 years, but issued for up to 5). Long enough that you don't think about it monthly; short enough that a leaked cert has bounded blast radius.
  • Self-signed because no public CA issues code-signing certs for arbitrary hobbyists patching consumer drivers. EV Code Signing certs from Sectigo / DigiCert require business verification (~$300-600/year) and won't issue if the patching activity violates AMD's EULA.

This is intentionally a lab tool. If you are deploying this in production at scale, you should either: (a) negotiate Server-class drivers from AMD directly, or (b) use a properly managed code-signing CA, not this self-signed model.


Disclaimer & at-your-own-risk acknowledgements

By running these scripts, you acknowledge:

  1. No warranty. The scripts are provided "as is" under MIT License. There is no guarantee that they will work on your hardware, will not damage your installation, or will be supported in future Windows updates. See LICENSE.

  2. You are the publisher of record. Patching AMD's INFs and re-signing them with your own certificate makes you — not AMD, not Microsoft — the cryptographic publisher of those drivers from Windows' point of view. If a patched driver causes a BSOD, system instability, or data loss, the bug is attributed to your self-signed cert, not to AMD.

  3. AMD's End User License Agreement for the chipset / graphics / Ryzen AI installers permits redistribution under specific terms. Re-signing modified INFs is a grey area; you should read AMD's EULA for your specific package and form your own judgement. This repository takes no position on whether your use is permitted under AMD's terms. For Ryzen AI specifically, the EULA must be accepted at https://account.amd.com/en/forms/downloads/ryzenai-eula-public-xef.html before downloading; the NPU script's I00 phase requires explicit I AGREE confirmation that this acceptance has occurred.

  4. Microsoft's Windows Hardware Lab Kit (HLK) certification is invalidated for any driver this pipeline replaces. WHQL-signed drivers carry Microsoft's attestation that they passed HLK; self-signed drivers do not. If you rely on Microsoft Premier Support for the affected hardware, your support contract may not cover issues caused by self-signed drivers.

  5. BitLocker, TPM, and Secure Boot interactions. The chipset script's PSP driver replacement (amdpsp.inf) interacts with Platform Security Processor firmware. On systems with BitLocker enabled, a failed PSP driver upgrade can trigger BitLocker recovery prompts on next boot. Always have your BitLocker recovery key recorded before running -Action Install on the chipset script.

  6. Anti-cheat software (Easy Anti-Cheat, BattlEye, Vanguard, etc.) may flag self-signed kernel-mode drivers. This pipeline is not intended for gaming workloads on competitive titles and may result in account bans if used as such.

  7. The 5-year cert expiry is real. Schedule a renewal task in your calendar for year 4.5 of any production deployment, or accept that drivers stop installing in year 5.

  8. Driver-category priority override (BREAKING change). The script's install-decision logic ranks self-signed drivers ([C]) above hardware-vendor drivers ([B]) and Microsoft generic drivers ([A]), regardless of driver version. On a clean WS2025 install this is exactly the intent — Microsoft's in-box generics will be replaced by AMD-vendor drivers carrying the script's signature. The trade-off is that any AMD-vendor driver already installed via Windows Update or an OEM package will also be overwritten by the script's self-signed equivalent (the binaries are the same; only the publisher differs). If you want to preserve a vendor driver, run -Action PrepareVerify first, inspect V06 Section 2, and decide whether to proceed. See SPEC §D.15 for the full rationale.

  9. NPU script (Deploy-AMDNpuDriverOnWindowsServer.ps1) is markedly higher-risk than its sister scripts. Specifically:

    • No physical-NPU validation has been performed by the maintainers as of this writing. All testing has been static analysis with psa.py and code-review of the AMD-published quicktest.py detection logic translated to PowerShell.
    • AMD account auto-download (Tier 2) is best-effort and may break without notice when AMD updates account.amd.com form layouts, CSRF handling, or the entitlenow.com CDN URL scheme. Always prefer Tier 4 (-OfflineZip) for reproducible runs.
    • Ryzen AI Software is officially Windows-11-only per AMD documentation (build >= 22621.3527). Even if the NPU kernel driver loads on Windows Server 2025, the user-mode stack (Python conda env, ONNX Runtime VitisAI EP, OGA) is not expected to function. Do not deploy the NPU script in environments expecting AI inference workloads on Server 2025.
    • Driver-store cleanup is best-effort. Removing self-signed NPU drivers from the driver store after -Action Install may require manual pnputil /delete-driver oemNN.inf /force or use of Driver Store Explorer (Rapr.exe).
  10. No commercial support is offered through this repository. GitHub Issues at https://github.com/usui-tk/Deploy-Drivers-For-WindowsServer/issues are best-effort for bug reports and clarification questions. Pull requests are welcome but not guaranteed to be reviewed on any timeline.


Troubleshooting

"OS detected: Windows Server 2025 (build 26100) [WS2025] but ProductType: 1"

You are running on Windows 11 24H2 (which shares NT build 26100 with Windows Server 2025). The script intentionally maps Win11 24H2 to the WS2025 profile because they share kernel ABI. Install phases are blocked on Workstation OS by default; use -Action PrepareVerify only, or pass -AllowWorkstationInstall if you really want to install on Win11 (read the warnings first). See TESTING.md for the pre-migration verification workflow.

"I02 aborts with PATH B PREREQUISITE NOT MET on Windows Server 2019 (Secure Boot ON)"

This is designed, fail-safe behaviour, and on WS2019 there is no tooling workaround: the WDAC supplemental-policy path requires the multiple-policy format introduced in Windows 10 1903 / build 18362, while WS2019 is 1809 / build 17763 — installing CiTool or extra tooling cannot enable it (the r95+ banner says this explicitly). With Secure Boot ON, bcdedit /set testsigning on is refused by firmware, so the legacy path is closed too. Your two options on such a host are: (a) disable Secure Boot in firmware and re-run with -UseTestSigning (Path B — save your BitLocker recovery key first), or (b) keep Secure Boot ON and re-run with -SkipNonCosignedDrivers, installing only the WHQL co-signed subset (Path A). See SPEC D.39.4.

"The script seems to hang mid-phase — and Ctrl-C makes it CONTINUE instead of stopping it"

That is not a hang: the console was in QuickEdit mark mode. Windows consoles (QuickEdit is ON by default on Windows Server) freeze every console write while text is selected, so an accidental click-drag stops all visible progress mid-Write-Host; Ctrl-C in mark mode is copy-and-release, which unfreezes the run without stopping it — the diagnostic signature of this failure class. r92+ disables QuickEdit for the duration of the run and restores the original console mode on exit, so this can no longer occur. On older revisions, avoid selecting console text during a run (or upgrade). Full post-mortem: SPEC D.38 (an 18m37s field freeze initially reported as a "7-Zip hang").

"Several [!] warnings appeared but the final state is Done — is it safe to proceed to Install?"

Yes — if the r92+ Install readiness line at the end of the RUN SUMMARY says READY. [!] lines are informational / expected-condition notices by design: source-INF baseline checks (errors on the unpatched INF are the baseline measurement), documented tool fallbacks (e.g. BthPan's inf2cat 22.9.8 refusal → makecat), untrusted-root before I01 imports the certificate, or a target device that is simply absent on this host (Install then stages the driver only). A real failure marks its phase as failed in the timing table and flips the verdict to REVIEW REQUIRED - failed: <ids>. SPEC D.38.4 documents the field analysis behind this.

"P02 takes 2-3 minutes to install the WDK"

The Windows WDK download is ~2.5 GB. This is a one-time install per machine. Subsequent runs reuse the installed inf2cat.exe and complete P02 in under a second.

"P03 fails with 'no AMD installer URL resolved'"

AMD periodically reorganises their support pages. The script probes 3-6 candidate URLs; if all return 0 hits, the parser broke. Workarounds:

  • 2026-07 AMD installer renaming: AMD renamed newly-published chipset installers from amd_chipset_software_<version>.exe to amd_software_<version>.exe. r91+ accepts both names and preserves the fetched landing pages as logs\amd-landing-probe-*.html when every probe misses; earlier revisions return 0 hits on current AMD pages — upgrade, or use -InstallerUrl below. See SPEC D.37.
  • Pass -InstallerUrl https://drivers.amd.com/drivers/... to skip URL discovery and download a specific version.
  • Open the Probe results: block in P03 output and visit each URL manually to confirm AMD's site changed.
  • File an issue: https://github.com/usui-tk/Deploy-Drivers-For-WindowsServer/issues

NPU script "All 4 download tiers exhausted"

This is the most common NPU-script failure. The EULA-gated AMD form requires an authenticated AMD account session that the script cannot fully simulate. Workarounds in priority order:

  1. Manually download the ZIP from https://ryzenai.docs.amd.com/en/latest/inst.html#install-npu-drivers, place it next to the script, re-run with -OfflineZip .\NPU_RAI*.zip.
  2. Try -AmdAccountUser / -AmdAccountPassword but expect breakage; AMD form structure changes are not announced.
  3. Capture the entitlenow.com URL from a browser session after manual EULA acceptance, pass via -InstallerUrl <captured-url>. The URL has a time-limited hash; download immediately after capture.

NPU script "No AMD NPU detected via pnputil"

The host has no AMD NPU device. Either:

  • This is intentional (pipeline-soundness check on a host without NPU): pass -AssumeIfMissing to proceed with the default Strix Point + RAI 1.7.1 profile.
  • This was unexpected (you believed you had a Ryzen AI machine): check Device Manager for unbound PCI devices; check Task Manager → Performance for an NPU0 entry; check that the BIOS has not disabled the NPU.

"V06 shows MS-GENERIC drivers on AMD hardware that the patched INFs don't cover"

CPU cores (cpu.inf), PCI Express Root Ports (pci.inf), Host CPU Bridges (machine.inf), USB xHCI (usbxhci.inf), HD Audio Controller (hdaudbus.inf) are all expected to remain on Microsoft generic drivers. AMD does not ship vendor drivers for these (they're enumerated by core OS subsystems). The "ALERT" message in V06 Section 1 is informational, not an error.

"I02 deploys WDAC policy but new driver still doesn't load"

Check eventvwrApplications and Services LogsMicrosoftWindowsCodeIntegrityOperational for events 3076 / 3077 / 3091. The Issuer / Subject / Thumbprint of the blocked signature should match your self-signed cert. If they don't match, the WDAC policy isn't deployed correctly — try CiTool -lp to list active policies.

"AMD driver was installed but Device Manager still shows MS generic on the device"

Run pnputil /scan-devices to force a re-enumeration. If still bound to MS, the patched INF's HWID may not match the device's PNP ID exactly. Check V06 Section 2 ("WILL be replaced" / "have no patched INF") — if the device falls into the latter category, no patched driver claims that HWID, which is expected for some devices (USB hubs, generic xHCI controllers, etc.).

"I02 appears to hang for 60+ seconds between 'Converting XML to .cip binary...' and 'Deployed:' lines"

Historical defect (now fixed in current mainline). CiTool.exe was invoked without the --json flag and printed "続行するには、Enter キーを押してください" (Press Enter to Exit) to the console, blocking the script on stdin. Pressing ENTER in the active console window resumed the script. This is fixed by passing --json to all CiTool.exe invocations, which suppresses the interactive prompt per Microsoft's CiTool design (the --json flag documents itself as "出力を json として書式設定し、入力を抑制する"). Upgrade the script and the hang will no longer occur. See SPEC §D.16 for the full root-cause analysis.

"CiTool log line shows mojibake like '蜃ヲ逅・・謌仙粥縺励∪縺励◆'"

Historical defect (now fixed in current mainline). This is the UTF-8 byte sequence of 処理が成功しました interpreted as cp932 (Shift-JIS). CiTool.exe writes UTF-8 to stdout, but PowerShell decoded it using the default ja-JP [Console]::OutputEncoding (cp932). SPEC §A.5 / §D.5 mandated UTF-8 enforcement at P00 but the implementation was missing. Fixed via Set-ConsoleUtf8 at P00. See SPEC §D.16.

"I03 says '3 failed' but I04 says 'Failed: 0' on the same install run"

Historical defect (now fixed in current mainline). I03's classification logic treated pnputil exit=259 (ERROR_NO_MORE_ITEMS) as a failure, but I04's PostInstallVerification reads the actual device state and correctly identifies these as REBOOT_NEEDED (when a sibling-INF first install already queued the binding) or as no-op (driver package already in store). The exit=259 cases are typically from duplicate-source INFs (e.g. Chipset_Software\SMBus Driver\W11x64\SMBUSamd.inf and SMBus Driver\W11x64\SMBUSamd.inf are both visited by I03, the second returns 259). The current I03 summary reports four categories — ok / need reboot / no-op / failed — and exit=259 maps to the no-op (already present) status (Write-Skip / DarkGray). See SPEC §D.17.

NPU script "I04 shows the device is bound but Ryzen AI Software won't initialize"

This is the expected outcome on Windows Server 2025. The kernel-mode driver loads, but the Ryzen AI Software user-mode stack (Python conda env, ONNX Runtime VitisAI EP, OGA) is officially Windows-11-only. Do not expect AI workload functionality on Server 2025. Either:

  • Use Windows 11 24H2 for actual NPU inference workloads.
  • Treat the Server 2025 install as kernel driver bring-up only (lab / research).

Chipset script "P08 reports '1 failed' for the CIR Driver folder" (or any other INF folder)

This is now handled automatically in mainline (Chipset r66+). The AMD Chipset Software package occasionally ships an INF whose [SourceDisksFiles] references files that AMD did not actually package in the sub-MSI's cabinet. The most reproducible cases are AmdAppCompat.inf, AmdAS4.inf, AMDCIR.inf, and usbfilter.inf in Chipset 8.05.04.516 on Renoir / WS2019: each declares one or more files in [SourceDisksFiles] that the cabinet does not include. inf2cat.exe therefore fails at P08 with error 22.9.1 ("driver package is missing some files"). The upstream cause is a SECREPAIR Error: 3 cascade visible in the sub-MSI's msiexec /a log.

In r65 the script started detecting this at P05 (new Get-InfReferencedFile helper cross-checks every patched INF's [SourceDisksFiles] against the files actually extracted by P04), recording the result in inf_inventory.csv via the new EligibleForCatalog column, and propagating the skip through P06 / P08 / V03 / V04 / V05 / V06 / I03. The expected P08 summary becomes tri-state (N ok / 0 failed / K skipped).

r66 closes a follow-on gap: P06 had been copying the AMD-shipped original .cat files alongside the ineligible INFs, and P09 then re-signed those orphans with the self-signed cert. r66 adds two cooperating defense layers — P08 now deletes orphan .cat files in skipped directories, and P09 additionally filters any survivors by directory. Net result: V01's Catalog files: N count now matches P08's N ok exactly, no orphan catalogs end up in patched/, and standalone P09 runs (-OnlyPhases P09) on a recovered workspace remain safe.

See SPEC §D.24 for the full root-cause analysis and the layered defense design, and CHANGELOG.md for the r65 (detect-and-skip) and r66 (orphan cleanup) entries. The submsi-failures-diag.txt pattern frequency now correctly classifies these 1603s as SECREPAIR missing source files (SPEC §D.21).

If you are still seeing P08 fail on r66, the affected INF is exhibiting a different failure mode — open an issue with the INF name and the full [P08] console block.


Development tools

psa.py — PowerShell Static Analyzer

The PowerShell static analyzer used to validate the pipeline scripts is psa.py. It is maintained as a single canonical artifact in a separate repository — usui-tk/ai-generated-artifacts — under quality-tools/powershell-static-analyzer/. This repository does not bundle a local copy; obtain psa.py via one of the methods below before using it.

A single-file Python 3 static analyzer that catches common PowerShell mistakes the regular parser does not flag.

Obtaining psa.py

Method 1 — Clone the canonical repository (recommended for ongoing development)

# Clone the canonical repository as a sibling directory to this repo
git clone https://github.com/usui-tk/ai-generated-artifacts.git ../ai-generated-artifacts

# Run from this repository's root
python3 ../ai-generated-artifacts/quality-tools/powershell-static-analyzer/psa.py Deploy-AMDChipsetDriverOnWindowsServer.ps1
python3 ../ai-generated-artifacts/quality-tools/powershell-static-analyzer/psa.py Deploy-AMDGraphicsDriverOnWindowsServer.ps1
python3 ../ai-generated-artifacts/quality-tools/powershell-static-analyzer/psa.py Deploy-AMDNpuDriverOnWindowsServer.ps1

Method 2 — Download the single file (recommended for one-shot CI runs)

Linux / macOS (curl):

curl -sSLO https://raw.githubusercontent.com/usui-tk/ai-generated-artifacts/main/quality-tools/powershell-static-analyzer/psa.py
python3 psa.py Deploy-AMDChipsetDriverOnWindowsServer.ps1
python3 psa.py Deploy-AMDGraphicsDriverOnWindowsServer.ps1
python3 psa.py Deploy-AMDNpuDriverOnWindowsServer.ps1

Windows PowerShell (Invoke-WebRequest):

Invoke-WebRequest `
    -Uri  "https://raw.githubusercontent.com/usui-tk/ai-generated-artifacts/main/quality-tools/powershell-static-analyzer/psa.py" `
    -OutFile psa.py
python3 psa.py Deploy-AMDChipsetDriverOnWindowsServer.ps1
python3 psa.py Deploy-AMDGraphicsDriverOnWindowsServer.ps1
python3 psa.py Deploy-AMDNpuDriverOnWindowsServer.ps1

In the rest of this document and in SPEC.md / TESTING.md / CONTRIBUTING.md, commands of the form python3 psa.py <script>.ps1 assume that psa.py has already been obtained via Method 1 or Method 2 above and is accessible on a path of your choice.

Checks performed

psa.py (latest mainline) ships a check set spanning the generic families PSA1xxx through PSA9xxx plus the project-pipeline convention family PSAP0xxx. The exact rule count grows as new defect classes are productionised upstream; this section names the families and notable recent additions rather than the raw count, to avoid mechanical drift each time a rule is added. The most recent additions:

  • PSA7003 (added in psa.py 4.2.0, non-ASCII script body) — a default-on warning that flags any non-ASCII character in a .ps1 body outside the BOM (em / en dashes, smart quotes, the section sign, the ellipsis, no-break spaces — the source-format defect class an ASCII-only CI gate rejects). This repository deliberately opts out of PSA7003 (disabled in .psa.config.json): the AMD-family scripts embed intentional Japanese log strings and em-dashes in their console output, so a non-ASCII script body is expected here rather than a defect. See SPEC.md §A.11.5.
  • PSA1004 / PSA2012 / PSA2013 (added in psa.py 4.1.0) — three error-severity, default-on static checks that close concrete latent-bug classes: bare (if/switch/foreach/while/...) parsed as a command call (PSA1004), positional call with insufficient args to a Mandatory-param function silently hanging unattended sessions (PSA2012), and $Script:Foo read but never assigned silently evaluating to $null (PSA2013). All four pipeline scripts in this repository pass with 0 findings at the r81 / r47 / r29 / r25 baseline (psa-py-v410-three-new-error-rules-baseline).
  • PSAP0005 (added in psa.py 4.0.0, the LLM-assisted-maintenance guardrail) catches any rNN reference inside a comment body, broader than PSAP0003's structured tag forms. This repository runs PSAP0005 in its default strict mode since the Chipset r80 / Graphics r46 / BthPan r28 / NPU r24 release (psa-py-v4-llm-governance-strict); the original psap0005_relaxed_mode: true baseline adopted at r76 has been retired and the key is omitted from .psa.config.json (see SPEC §A.13 Migration roadmap — status COMPLETED — and §D.34 for the retrospective).
  • PSA2009 (added in 3.8.0) is the static-analysis counterpart of the runtime defect that caused Chipset r72 P05 -> FAILED with "WhqlCoSignAnalysis" property-not-found exception on a Japanese-locale Windows Server 2019 host.
  • PSA2010 / PSA2011 (added in 3.9.0) would have caught the r75 §D.33 Defect A (Split-Path binder bug) and the §D.32.2 Find-Signtool family of typos at static-analysis time.

See SPEC.md §A.11.5c / §A.11.5d / §A.11.5e / §A.11.5f for the repository-side commentary on PSA2009 / PSA2010 / PSA2011 / PSA1004+2012+2013, and SPEC.md §A.13 for PSAP0005's repository-side policy. This repository validates its scripts against the latest mainline psa.py (no fixed-version pinning); see SPEC.md §A.11 Version policy for the rationale and the LLM / AI workflow for adopting a new version. The rules are grouped into the following ten categories:

Category Code range Examples
Syntax balance PSA1001..PSA1004 brace / paren / bracket balance, bare (if/switch/foreach/while/...) used as expression (PSA1004, new in 4.1.0)
Semantics PSA2001..PSA2013 undefined variable, auto-variable shadowing, -match against bare variable, $null on the right of -eq/-ne, assignment / redirection inside conditional, parameter shadows auto-variable (PSA2007), $Script:Foo++ without init (PSA2008), PSCustomObject property assigned without prior declaration (PSA2009), call to undefined function (PSA2010, error), Split-Path -LiteralPath ... -Parent triggers AmbiguousParameterSet on PS 5.1 ja-JP (PSA2011, error), positional call with insufficient args to a Mandatory-param function (PSA2012, error, new in 4.1.0), $Script:Foo read but never assigned (PSA2013, error, new in 4.1.0)
Coding pattern PSA3001..PSA3006 Start-Process -ArgumentList, trailing backtick before empty line, -match against empty string, empty catch block, Start-Transcript -Path should be -LiteralPath, Get-WmiObject / Invoke-WmiMethod etc. (prefer CIM cmdlets)
Hygiene PSA4001..PSA4004 unfinished markers (TODO / FIXME / XXX / HACK), trailing whitespace, long line, trailing semicolon
Security PSA5001..PSA5004 plain-text password parameter, Invoke-Expression, broken hash algorithm, hardcoded ComputerName
Best practice PSA6001..PSA6008 non-approved verb, cmdlet alias, plural function noun, $global: definition, mandatory parameter with default, switch defaulting to $true, missing [OutputType()] declaration, function attribute without param() block
File format PSA7001..PSA7002 missing UTF-8 BOM on .ps1 (Windows PowerShell 5.1 ja-JP falls back to Shift-JIS / cp932 without BOM), LF-only / mixed line endings
Cross-file consistency PSA8001 function body hash drift across files in the same scan — enforces that shared helper functions (Format-Elapsed, Write-Detail, Start-DebugTrace family, etc.) stay byte-for-byte synchronised across the four pipeline scripts
Complexity metrics PSA9001..PSA9002 function-body length threshold (off by default), external-process invocation without $LASTEXITCODE check (off by default)
Project / pipeline conventions PSAP0001..PSAP0005 phase function naming convention, required script-identifier variables, new in 3.3.0: inline # rNN: revision-tag comments (PSAP0003), end-of-file REVISION HISTORY blocks (PSAP0004), new in 4.0.0: any rNN reference in a comment body, broader than PSAP0003 (PSAP0005, run in strict mode by this repository) — all PSAPxxxx rules are off by default; this repository opts in to all five

For the authoritative specification of every rule, see quality-tools/powershell-static-analyzer/SPEC.md §4 in the ai-generated-artifacts repository.

Repository-specific configuration

This repository ships its own .psa.config.json at the repository root. It is the canonical configuration for the four pipeline scripts and does three things:

  1. Opts in to PSAP0001, PSAP0002, PSAP0003, PSAP0004, and PSAP0005 so that the 21-phase naming convention (Invoke-(Prep|Verify|Inst)PhaseNN_DescriptiveName), the script-identity trio ($Script:ScriptVersion / ScriptHash / ScriptShortTag), and the revision-discipline rules (PSAP0003 forbids inline # rNN: tags; PSAP0004 forbids in-script REVISION HISTORY blocks; PSAP0005 in strict mode forbids any descriptive rNN-anchored prose in comment bodies — history lives in CHANGELOG.md and design rationale in SPEC.md Part D) are all enforced.

  2. Configures PSA8001 (cross-file function-body drift) with psa8001_ignore_functions, listing roughly 45 function names that are intentionally per-script (phase functions, per-driver-family helpers, Show-Help, etc.). Shared helpers NOT listed there MUST stay byte-for-byte identical across all four scripts.

  3. Disables PSA4003 (long line) because the pipeline scripts intentionally use multi-clause -f format strings that exceed 120 columns for readability.

Run static analysis against all four pipeline scripts via:

# From the repository root, after psa.py has been obtained (Method 1 or 2 above)
python3 path/to/psa.py --config ./.psa.config.json \
    Deploy-AMDChipsetDriverOnWindowsServer.ps1 \
    Deploy-AMDGraphicsDriverOnWindowsServer.ps1 \
    Deploy-AMDNpuDriverOnWindowsServer.ps1 \
    Deploy-MSBthPanInboxOnWindowsServer.ps1

All four scripts MUST be passed in a single invocation for PSA8001 cross-file analysis to work; with a single file PSA8001 has no peers to compare against and emits nothing. See CHANGELOG.md for the current verified baseline.

Exit codes: 0 = clean, 1 = warnings only, 2 = errors. Useful in CI:

# .github/workflows/lint.yml example (Method 2 — single-file download)
- name: Fetch psa.py from canonical repository
  run: |
    curl -sSLO https://raw.githubusercontent.com/usui-tk/ai-generated-artifacts/main/quality-tools/powershell-static-analyzer/psa.py
- name: Static-analyze PowerShell scripts
  run: |
    python3 psa.py --config ./.psa.config.json \
        Deploy-AMDChipsetDriverOnWindowsServer.ps1 \
        Deploy-AMDGraphicsDriverOnWindowsServer.ps1 \
        Deploy-AMDNpuDriverOnWindowsServer.ps1 \
        Deploy-MSBthPanInboxOnWindowsServer.ps1

For the full design rationale, output format reference, and an extended CI integration example, see the canonical README at quality-tools/powershell-static-analyzer/README.md in the ai-generated-artifacts repository.


Developer specification

For the full developer specification — including phase architecture rules, banner / log conventions, parameter naming conventions, CSV / JSONL output format, path-handling rules (-LiteralPath), and the quality gates enforced by psa.py — see:

  • SPEC.md — Developer specification (the authoritative reference for contributors and AI assistants working on this codebase). English only per the repository-wide documentation language policy (see SPEC.md §A.12).

SPEC.md is structured in three parts:

  • Part A — Common Specification. Reusable rules across the four scripts (phase architecture, banner / log markers, parameter conventions, error handling, CSV column conventions, path-handling rules). Pick this up first if you are extending any of the four scripts or adding a fifth.
  • Part B — Script-specific Specifications. One section per script (Chipset / Graphics / NPU) documenting the unique platform-detection logic, INF inventory filters, installer source resolution tiers, and known platform quirks.
  • Part C — Quality Gates & Lessons Learned. What psa.py checks for, what regression tests TESTING.md covers, and the historical fixes (e.g. timezone-induced DriverDate false positives in an earlier chipset revision) that are baked into the current implementation.

If you are adding a new feature, the recommended workflow is: read SPEC.md → read the relevant script's existing Invoke-*Phase*_* functions → make changes → run python3 psa.py <script>.ps1 (after obtaining it per Development tools) → update TESTING.md with any new regression scenarios.


File encoding

PowerShell scripts (*.ps1)

All *.ps1 files in this repository are checked out as UTF-8 with BOM and CRLF line endings on every platform. This is the canonical encoding for PowerShell 5.1 + 7.x scripts that contain non-ASCII characters (the Japanese log strings inside Write-Skip / Write-Caution calls). The .gitattributes rule that enforces this is:

*.ps1 text working-tree-encoding=UTF-8 eol=crlf

A note on git's internal storage: git applies standard text normalization at commit time. The blob inside the repository stores BOM + LF (line endings normalized to LF). On git clone / git checkout, git converts LF back to CRLF for *.ps1 files thanks to the eol=crlf directive, so the file on disk is BOM + CRLF — which is what Windows PowerShell expects. The BOM is preserved as content bytes in both forms.

Caveat for raw downloads: if you download a .ps1 file via the GitHub "Raw" button or curl https://raw.githubusercontent.com/.../*.ps1, you receive the blob form directly (BOM + LF) — git's checkout-time conversion does not apply to raw blob downloads. PowerShell 5.1 and 7.x handle both LF and CRLF in scripts correctly, so the file still executes, but if you need the exact canonical form (BOM + CRLF) you should clone the repository rather than downloading individual raw files. Practical recommendations:

  • For execution on Windows: clone the repo (git clone https://github.com/usui-tk/Deploy-Drivers-For-WindowsServer.git), don't right-click → "Save raw as" individual files.
  • For inspection or quick patching: raw downloads are fine; PowerShell tolerates LF line endings.
  • For re-publication or mirroring: if you re-host the scripts elsewhere, regenerate them as BOM + CRLF to match the canonical form.

Markdown documents (*.md)

All *.md files (README.md, README.ja.md, TESTING.md, SPEC.md, CHANGELOG.md, CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md) are stored and checked out as UTF-8 without BOM with LF line endings — the GitHub-native convention for Markdown rendering. The .gitattributes rule:

*.md text eol=lf

If you edit these files on Windows with an editor that auto-injects a BOM into .md files (some older Notepad++ versions do this), strip the BOM before committing or let .gitattributes normalize on next checkout.

Console output and the Japanese log strings

The Japanese log strings inside the .ps1 scripts are designed to render correctly on a ja-JP Windows console that is set to UTF-8 (chcp 65001). If your console is at the default ja-JP code page (932 / Shift-JIS), Japanese strings may garble. The scripts include a [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 call in P00 to enforce this, but if you redirect output to a file via *>&1 | Tee-Object, set your file encoding explicitly to UTF-8 to avoid double-encoding.

Programmatic emission of .ps1 content (Python helpers, AI agents, code generators)

If you ever produce .ps1 content from a program (a Python helper script, a Bash heredoc, an AI agent that writes files, a code generator that synthesises new helper functions), you must ensure the bytes you emit conform to the UTF-8 + BOM + CRLF contract before they reach disk. Language defaults are uniformly wrong for this — Python's """...""" triple-quoted strings, Node's template literals, Go raw strings, and shell heredocs all emit LF-only output on Linux / macOS regardless of the destination file's convention. A .ps1 file with mixed line endings (some lines CRLF, others LF) will pass pwsh -ParseFile cleanly and look identical in any visual diff, but a byte-level check reveals the defect — and on a strict-CRLF consumer (some signtool builds, certain MSI authoring tools) it will fail at use time.

The canonical reference for the per-file-type contract, the corrective tooling patterns (Python open(..., 'wb') + explicit BOM + \n\r\n), and the pre-commit verification commands is SPEC §A.2 (subsections A.2.1 through A.2.4). The full forensic trail of the one occurrence of this defect that reached this repository — caught and silently corrected by .gitattributes at commit time — is recorded in SPEC §D.23.


References

Microsoft Learn

AMD

This repository


License

MIT License. Copyright (c) 2026 contributors.

The MIT licence applies to the PowerShell scripts and accompanying documentation in this repository only. The scripts download AMD installer EXEs and Ryzen AI driver ZIPs at runtime and do not redistribute AMD's binaries, INFs, or catalogs. AMD's redistribution terms apply to those files independently.

Third-party attribution for code embedded in the scripts (the static ISSetupStream decoder, informed by the MIT-licensed ISx project) is recorded in THIRD-PARTY-NOTICES.md.


Contributing

See CONTRIBUTING.md for issue templates, PR guidelines, and how to run the regression test suite (including psa.py).

Issues and pull requests are tracked at: https://github.com/usui-tk/Deploy-Drivers-For-WindowsServer

Additional community documents:

  • CODE_OF_CONDUCT.md — Expected behaviour when interacting through Issues, Pull Requests, and Security Advisories. Tailored to the safety implications of self-signed kernel-mode drivers.
  • SECURITY.md — How to report security-impacting defects (driver-signing flaws, WDAC policy scope errors, credential exposure). Do NOT file these as public Issues — use the private Security Advisory channel instead.
  • CHANGELOG.md — Chronological per-release change log, organised by date and by script.

About

Install AMD consumer Ryzen chipset, Radeon graphics, Ryzen AI NPU (XDNA), and the Microsoft inbox Bluetooth PAN driver on Windows Server 2016/2019/2022/2025 by INF ProductType=3 patching, self-signed catalogs, and a WDAC supplemental policy that keeps Secure Boot on. 21-phase pipeline per script, idempotent, MIT-licensed.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages