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.
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 を参照してください。
- Why this exists
⚠️ Disclaimer (read before running)- Current status: not ready for end-user use
- What's in the box
- What's new
- Risk classification of the four scripts
- Scope of coverage
- Folder layout
- Quick start
- BthPan-specific quick start
- NPU-specific quick start
- Pipeline architecture (21 phases)
- Parameters (per script)
- Output files
- UEFI Secure Boot baseline
- Console output format
- System requirements
- Self-signed certificate: expiry, renewal, and revocation
- Disclaimer & at-your-own-risk acknowledgements
- Troubleshooting
- Development tools
- Developer specification
- File encoding
- References
- License
- Contributing
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
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:
- 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). - 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 withProductType=3(Server), leaving the original Workstation entries intact (so the patched INF is bi-compatible). - Generating a fresh
.catcatalog withinf2cat /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 makespnputilaccept 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).
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 Installon 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 Install→Graphics Install→MSBthPan 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 viadel C:\Windows\System32\CodeIntegrity\SiPolicy.p7brestored 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 deployedSiPolicy.p7bagainst 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
Installaction 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-UseTestSigningrun. 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 CheckpointorVMware Revert to Snapshotyou can call before-Action Installand 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 captureC:\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 Installon 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 Installon 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 V06before running the next script. RunningChipset Install→Graphics Install→MSBthPan Installback-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.
🚧 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
mainand 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.
| 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.
- 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.
- P2 audit remediation — E2E coverage corrections, lab/production wording separation, sister-duplication policy.
- 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.
| 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).
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 toolkitamd-npu-research-v1.0.0(no product script changes, no version bumps): addstools/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 underpublic/**(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 orReviewRequired; 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 areReviewRequired, 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, andpublication-manifest.jsonrecords path, length and SHA-256 for all 22 payload files withHandEdited: falsethroughout, 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 aProductTypeserver exclusion support static-candidate reasoning only, and the Ryzen AI Z2 Extreme evidence is Windows client runtime only..gitattributesstores this toolkit'spublic/**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 toolkitamd-graphics-research-v1.0.0(no product script changes, no version bumps): addstools/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 underpublic/**(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, andpublication-manifest.jsonrecords size, SHA-256, generation mode and originating source hash for all 64 payload files withHandEdited: falsethroughout. 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..gitattributesstores this toolkit'spublic/**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 toolkitamd-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-erainventory/accepted-baseline/snapshot model is retired in favour of a single allow-listed generated surface,public/**, defined by the newPUBLICATION-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 releases2.04.04.111through8.07.16.1035, aggregate indexes, 28 reports, and apublication-manifest.jsonrecording size, SHA-256, generation mode and originating source hash for all 64 payload files (HandEdited: falseon 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.xmland/DevID.xmlare 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 enumerablevaluewhose length matchesCount, 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 topublic/inventory/amd-chipset-driver-inventory.csv(643 rows, same schema); theinventory-reconciliationtool 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 canonicaldeployment-plan.jsonafter the-SkipNonCosignedDriverstrim and before the first INF mutation — the audit's logical contractSourceArtifact -> PackageInventory -> DeploymentPlan -> PatchedArtifactsmade real. Every row carries the audit's field set:Inf/SelectedSourceInfPath/SelectedSourceInfSha256(the content identity),Devices[]from the rich W13 detail,SourceVariant,SelectionReason,ExpectedMutation,WdfDecisionwith the typed observation attached,PackageCompletenessDecision(chipset reports its phantom-reference evaluation — the machinery the audit endorsed over the research shortcut; graphics honestly reportsEvaluated=false),KernelTrustObservation(CoSigned/NotCoSigned/NotAnalysedfrom the P05 WHQL analysis — an observation, never a loadability claim), and per-selectionPayloadFiles[]SHA-256 (the W13 Q-W13-1 deferral repaid: chipset enumerates[SourceDisksFiles*]viaGet-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 (NeedsPatchalready impliesVariantSelectedANDEligibleForCatalogat 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-rowOutcome+PatchedInfSha256keyed to the plan SHA — theinstalled -> patched INF SHA -> source INF SHAreverse lookup. P08 and I03 run a report-only alignment check that names out-of-plan INFs underpatched/(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, canonicalkey=valuelines, lowercase SHA-256; fixture-testable with no I/O) fingerprints each phase's declared input and output field sets, andTest-PhaseMarker -ExpectedInputFieldsturns a marker into a content-addressed cache entry — a legacy schema-less marker is a miss by design,-Forcestill always misses, and every miss names which side diverged. P03 no longer trusts the newest download byLastWriteTime: 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 canonicalpackage-inventory.json— every record keeps its historical fields and gainsSourceArtifactSha256/InfSha256/InspectionStatus/ typedWdf.KMDF|UMDFevidence ({ Status, Versions[], Evidence[] }with 1-based line numbers, five-value vocabulary, Unknown is never Compatible); an unreadable INF becomes aParseFailedrecord 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 staticISSetupStreamdecoder (C#, ISx-informed, MIT — attribution retained in-block and recorded in the new rootTHIRD-PARTY-NOTICES.md) is ported verbatim into the chipset script through a new source-fragment mechanism:tools/source-fragments/AmdStaticExtraction.fragment.ps1is 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-versionedname.infNvariant 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; anInfs[]table with resolved names and variant indices; aParityNotecomparing 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).-Forceno 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-AllowUnverifiedDownloadswitch (chipset/graphics), which reaches exactly the AMD installer sites and continues a FAILED verification as operator-attested-unverified with a loud warning; hosts whereGet-AuthenticodeSignaturecannot run surface asHostCannotVerifyunder 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 writessource-artifact_<file>.jsonbeside 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-09Test-DownloadOverrideSeparation.ps1pins all of the above (negative control against the pre-W8 tree: 33 named failures);Write-SourceArtifactEvidencejoins 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-RandomPfxPasswordandSet-PfxFileAclare adopted byte-identically (three-way → four-way), the Ctx injects a per-run random 32-char CSPRNG password when-PfxPasswordis 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 fieldAmdSuppPolicyIdis renamedMsBthPanSuppPolicyId(the marker file already carried the product-correct name). New gate G-07Test-NpuPfxHygiene.ps1pins 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-WdacBasePolicyGuidrequired, 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 thebcdeditwrite 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-05Test-RetiredSigningNarrative.ps1scans 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-10Test-DocumentationStateConsistency.ps1pins 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 nowPROJECT_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-MeasuredDriverRankReportcaptures the actual PnP candidate list viapnputil /enum-devices /drivers(parsed by a new fixture-tested pure function; optionalRank: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-Forceas a loud-warning escape hatch for CDN quirks). P1-G: the fixedChangeMe!2026PFX 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 caseTest-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 helperResolve-SupplementalActivationPlan(fixture-tested) pickscitool/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 aUseTestSigningconditional pinned in the AST by the new gate G-04 caseTest-InstallPathMutationGuard.ps1(also: no Windows Driver Policy GUID to a removal verb, nonointegritychecks, 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 derivesBootSigningPostureinstead —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-WhqlCoSignatureadditionally emits the P1-DClassificationvocabulary (WhcpHdc/LegacyCrossSignedNotProven/PrivateOrTestSigned/Unsigned/Unknown; the AllowListed value is reserved and never emitted — ruling Q4). New offline caseTest-BootSigningPostureSweep.ps1holds 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-23SiPolicy.p7bdeletion, 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-WdacBasePolicyGuidnames 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-WdacBasePolicyGuidparameter it never had (the GUID was hardcoded at the call site). New test caseTest-SupplementalPolicyGate.ps1pins 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 declaresinstall 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.DegeneratePlanwas 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 (-UseTestSigningon a Secure Boot host) and a per-phase call so-OnlyPhases I02cannot 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 twoGet-WinEventerrors 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-SkipNonCosignedDriversand-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 sameWdf01000.sysreads1.27.17763.1192numerically and1.27.17763.1as 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 —-SkipNonCosignedDriversfound no WHQL co-signature on any in-scope INF, so P06 closed asskippedand P08/P09 respected that, all exactly as designed; then V01 threwrun earlier phases firstabout 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 closesskippedlike P08 and P09. The host UMDF version was never measurable — it was read fromWudfRd.systhe way KMDF is read fromWdf01000.sys, which on this host yields10.0: the operating system version.Wdf01000.sysreally is1.27.…butWudfPf.sys,WUDFRd.sysandWUDFHost.exeare all10.0.17763.9020, and the documented UMDF version for that build is 2.27, carried by no binary. Because10.0compares 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 READYis 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 ininf_inventory.csvfrom all four scripts (IsWdfDriver,KmdfLibraryVersion,UmdfLibraryVersion,CoInstallerVersions,WdfSectionCount). The failure this addresses is quiet:inf2cat /os:Server2016_X64sets the catalog's target OS and does not lower a driver's KMDF requirement, so a package declaringKmdfLibraryVersion = 1.33can 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; followingKmdfService =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 strings1.19sorts below1.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 shipfindstr. Stages 8-16 never ran, on the one machine that needed them. The mistake was not usingfindstr; 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 justdiroutput, everyWdfCoInstaller*.dllwith the framework version its name encodes, the services depending onWdf01000(the suspect pool whenWDF_VIOLATIONfires), 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 predictsWDF_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,setupapilogs, 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-SkipEvidenceCollectionin r94). See "Configuration evidence collector (r93+)" below.
-
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 viareg save, the live registry queried without a hive load, andCrashDumpEnabled = 0x7reported on the console, answering the question that motivated running this before a reboot. Stage 12 then aborted: inside aCALLed subroutine cmd.exe resolves argument modifiers before deciding a line is a comment, andremis 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 legitimateFOR-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.cmdcompleted 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:CrashDumpEnabledwas 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 usesreg saveinstead of copying locked hives, the liveCurrentControlSetinstead of a loadedControlSet001, anddism /onlineinstead of/image:.CrashDumpEnabledandAutoRebootare echoed to the console — a value of0means 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 as0 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.cmdran for the first time and stopped part way through stage 5. A label containing parentheses —CBS (incl. CBS.persist.log)— was expanded inside anifblock, 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 withgotonow, so a future label containing(,&or|cannot re-create the fault. The test suite had passed the broken file because it checked encoding,gotoresolution andreg loadbalance 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.cmdnow 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 notC:) 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 withgit 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 aWDF_VIOLATIONbugcheck loop on Windows Server 2016 and by this project's first WS2016 measurements. The collector now recordsdriver-framework.json— the KMDF/UMDF runtime version, which is a hard ceiling: a driver whose INF declares a newerKmdfLibraryVersioncannot load, and that is not a signing failure, so neither Path A nor Path B moves it (inf2cat /os:Server2016_X64changes the catalog target, not the KMDF requirement) — andcrash-evidence.json, whose bugcheck events carry the stop code and all four parameters; forWDF_VIOLATIONthe first parameter names which framework contract was violated. NewCollect-OfflineRecoveryEvidence.cmdcollects 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_UpdateAndCompareCIPolicyis present on 14393.9339, not absent), and independently reproduced thevwifibusprediction 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 closedSKIPPED, 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 addsos-capability.json(which per-build profile the scripts would select, fourteen cmdlets, six CIM classes including the one absent on WS2016, and whethersigntoolis present — a WHQL verdict without it is a default, not a measurement) andarchive-capability.json(provesCompress-Archiveworks 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 withImagePathExistspopulated 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-likepattern containing an unterminated[character class, which throws before matching anything and killed the run; and all twelve stages inside onetrywith 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-levelfinallymatching the four deploy scripts, and a newCollection completenessrow 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) —-SkipNonCosignedDriverscannot 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,ServiceBinaryPresentwas never populated, and the assessment rowDriver binary presencereported PASS on a host with a missing binary. No static gate could catch it:psa.pyand 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.ps1files 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 emitsservices.json(every service, unfiltered — user-mode, kernel drivers and registry-only keys, with resolvedImagePathand an on-disk existence test, plus a reverse dependency index) andserver-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)-SkipNonCosignedDriversanalysed 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 = 0had 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 carriesPlanUnverifiedCounton which the I02 short-circuit is fail-closed. (2) An Intel adapter was re-enumerated 32 ms after apnputil /installrelated-drivers pass and its re-install failed on a service binary absent from this Server SKU;/installis 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 serviceImagePathexistence 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-SkipNonCosignedDriversPath 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'toWrite-PhaseFooter, whose canonValidateSetpermits onlydone/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 aSystem.Collections.Generic.List[object]throws in the binder itself — present since r92, so both earlier attributions (r95Get-Variableprobe, r96variable: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 completedPrepareVerify -SkipNonCosignedDriversend-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, newPlanCatalogSignCount), gates I01 on "no catalogs to self-sign" only, corrects the install-phase messages, and rewrites the readiness-digest probe onto the exception-freevariable: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-SkipNonCosignedDriversfield 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 thePrepareVerify->Installboundary, 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 -Scopeon 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 I02PATH Bbanner 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 (ListPhasesexcepted) — the opt-in-CollectEvidencewas 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 (*.pfxprivate 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-LogFileneeded), and the Chipset URL discovery accepts AMD's 2026-07 installer renaming (amd_chipset_software_<v>.exe→amd_software_<v>.exe; SPEC D.37) with probe-miss evidence preservation underlogs\. -
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 centralai-generated-artifactsrepository. 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.
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 download — bthpan.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:
- Do not run
-Action Installon a host you cannot afford to roll back. The cleanup path is implemented but driver-store removal is best-effort and may require manualpnputil /delete-driver oemNN.inf /forcecleanup. - 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.
- There are no physical-NPU validation runs yet. All current verification is static analysis with
psa.pyand code-review of the AMD-publishedquicktest.pydetection logic translated to PowerShell. Real hardware behaviour is unconfirmed. - AMD's account auto-download flow can break without notice. AMD periodically updates their
account.amd.comform 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.
- 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 build32.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 build32.0.203.314(RAI 1.6.1) or newer. - Krackan Point (
PCI\VEN_1022&DEV_17F0&REV_20) — Ryzen AI 200 series. Driver build32.0.203.314(RAI 1.6.1) or newer.
- Phoenix / Hawk Point (
- 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_BTHPANshows as Unknown Device (code 28), or shows Status=OK but withDriverInfPath=bth.infandClass=Bluetooth(Phantom OK;bthpan.sysis NOT loaded andBthPanservice is NOT running). - Verified true-resolution criteria:
DriverInfPath=oem*.inf,Class=Net,Service=BthPan,C:\Windows\System32\drivers\bthpan.syspresent,BthPanservice registered, a Bluetooth PAN NetAdapter visible toGet-NetAdapter.
- HWID:
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.
- 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.
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
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
-WdacBasePolicyGuidnames a base policy you have verified exists: a WDAC supplemental Code Integrity policy toC:\Windows\System32\CodeIntegrity\CiPolicies\Active\, activated viaCiTool --update-policywhere 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+).
- Windows Server 2025 host (build 26100), or Windows 11 24H2 (build 26100) for preview-only verification (the script will block
Installphases on Workstation OS unless-AllowWorkstationInstallis 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).
# 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# 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 -AssumeIfMissingPrepareVerify 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.infin the host's ownC:\Windows\System32\DriverStore\FileRepository\bthpan.inf_amd64_*directory. P03 fails only on hosts where the inbox driver has been deliberately removed (extremely rare).
🆘 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-VMSnapshotto roll back to seconds after a badInstall. Server SKU System Restore is OFF by default and even when on does not roll backSiPolicy.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
Installaction completes, I04 (PostInstallVerification) explicitly distinguishes Phantom OK from true resolution. The script prints*** TRUE RESOLUTION ACHIEVED ***only whenbthpan.sysis loaded,BthPanservice is running, andBTH\MS_BTHPANreportsClass=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. TheInstallaction requires extra preconditions (offline ZIP availability or AMD account credentials) and is not recommended without physical NPU hardware.
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.
-
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 beD:orE:here. Rundiskpart,list volume, find the volume with the Windows installation, note its letter, thenexit. The examples below useC:— 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>.infentries 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.p7bdeployed 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.p7bIf 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.
-
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.
-
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:anddelcommands from that second machine. This is slower than option 1 but covers cases where the failed host won't boot any external media. -
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.
# 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 ListPhasesThe 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.
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..\Deploy-MSBthPanInboxOnWindowsServer.ps1 -OnlyPhases V06V06 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. |
.\Deploy-MSBthPanInboxOnWindowsServer.ps1 -Action All -CleanWorkRoot-Action All runs all 21 phases (P00-P09 → V01-V06 → I00-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 ***.
# 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 BIn 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.
# 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_DriverInfPathReminder: 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.ps1will refuse-Action Installand-Action Allon 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.
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:
- https://ryzenai.docs.amd.com/en/latest/inst.html#install-npu-drivers
- Click the appropriate driver link for your detected NPU (e.g. NPU Driver 32.0.203.314 for STX/KRK, RAI 1.6.1).
- Sign in to your AMD account, accept the EULA, save the ZIP locally (typical filename:
NPU_RAI1.6.1_314_WHQL.zip).
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# 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 recordedAfter 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.
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.PasswordCommon pitfall: running
-Action Install -NpuOverride STX -NpuDriverPackage NPU_RAI1.6.1_314without specifying any download source will fall through to Tier 4 auto-scan and silently use whateverNPU_RAI*_WHQL.ziphappens to be in~/Downloads— which may or may not match the package you specified. Always pin the source explicitly.
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-PnpDevice → Disable/Enable-PnpDevice → pnputil /remove-device /scan-devices → Stop/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. |
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.
| 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 |
| 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.
| 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.
-NpuDriverPackageand-RyzenAiSoftwareVersionare therefore independent switches; you can combine any driver with any software (e.g.-NpuDriverPackage NPU_RAI1.6.1_314 -RyzenAiSoftwareVersion 1.7.1).
| 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/-OfflineZipparameters, because there is no remote installer to fetch — the driver is the host's ownbthpan.inffromC:\Windows\System32\DriverStore\FileRepository\bthpan.inf_amd64_*.
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 |
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 |
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.
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).
The snapshot combines two sources:
-
Embedded inventory — direct reads via
Confirm-SecureBootUEFI,Get-SecureBootUEFI db/kekfor 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-Updatescheduled task state (viaGet-ScheduledTaskfor locale-independent results on ja-JP hosts). -
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-OutputPathcontaining:(every absolute Windows path).
| 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.
- 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
UEFICA2023Errorindicates 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.
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.
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 | 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.)
========================================================================
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.
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 $logKey properties:
- Console keeps its
Write-Host -ForegroundColordecoration 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 cleanup —
Stop-Transcriptis invoked from the top-levelfinallyblock and from aPowerShell.Exitingengine event handler as a fallback. - Operator-specified path inside
-WorkRoot+-CleanWorkRoot— the pre-existing relocation guard still applies to explicit-LogFilepaths (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 |
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.
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_MODEfor 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 asfailedin 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\andinf_inventory.csvinto<ScriptName>_<Action>_run-artifacts_<yyyyMMdd-HHmmss>_<PID>.zipand copies the zip next to the script, so one file can be handed over for analysis.*.pfxprivate keys are never included; the bulkdownload\/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%). Alogs\run-artifact-archive-plan.txtmarker records the planned zip name inside the archive itself. OnCleanupruns (workspace already wiped) the archive is skipped.
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.ps1Since 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 outCollector 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.
- CPU: For AMD scripts: AMD Ryzen 4000 series or newer (the script's
Get-AmdChipsetPlatformheuristic 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-PowerShellEnvironmentphase 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.comand*.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=OKin 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.
The certificate generated in P07 is the trust anchor for every patched driver this pipeline installs. It deserves its own section.
- 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\orC:\Temp\Workspace_Microsoft-BthPan\cert\. On all four sisters the PFX password is a per-run random 32-char CSPRNG value when-PfxPasswordis 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
.catfile underpatched\, the WDAC supplemental policy, and (via I01)LocalMachine\Root+LocalMachine\TrustedPublisher.
After the certificate expires:
- The catalog signatures embedded in
.catfiles 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-driverwill 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.
# 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-ItemIf 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-ComputerAfter reboot, re-run the full pipeline to generate a new cert.
- 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.
By running these scripts, you acknowledge:
-
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. -
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.
-
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 AGREEconfirmation that this acceptance has occurred. -
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.
-
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 Installon the chipset script. -
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.
-
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.
-
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 PrepareVerifyfirst, inspect V06 Section 2, and decide whether to proceed. See SPEC §D.15 for the full rationale. -
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.pyand code-review of the AMD-publishedquicktest.pydetection logic translated to PowerShell. - AMD account auto-download (Tier 2) is best-effort and may break without notice when AMD updates
account.amd.comform 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 Installmay require manualpnputil /delete-driver oemNN.inf /forceor use of Driver Store Explorer (Rapr.exe).
- No physical-NPU validation has been performed by the maintainers as of this writing. All testing has been static analysis with
-
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.
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.
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.
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").
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.
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.
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>.exetoamd_software_<version>.exe. r91+ accepts both names and preserves the fetched landing pages aslogs\amd-landing-probe-*.htmlwhen every probe misses; earlier revisions return 0 hits on current AMD pages — upgrade, or use-InstallerUrlbelow. 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
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:
- 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. - Try
-AmdAccountUser/-AmdAccountPasswordbut expect breakage; AMD form structure changes are not announced. - 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.
The host has no AMD NPU device. Either:
- This is intentional (pipeline-soundness check on a host without NPU): pass
-AssumeIfMissingto 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.
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.
Check eventvwr → Applications and Services Logs → Microsoft → Windows → CodeIntegrity → Operational 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.
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.
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.
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.
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).
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.
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.
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.ps1Method 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.ps1Windows 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.ps1In 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.
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 inpsa.py4.2.0, non-ASCII script body) — a default-on warning that flags any non-ASCII character in a.ps1body 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 ofPSA7003(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. SeeSPEC.md§A.11.5.PSA1004/PSA2012/PSA2013(added inpsa.py4.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:Fooread 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 inpsa.py4.0.0, the LLM-assisted-maintenance guardrail) catches anyrNNreference inside a comment body, broader thanPSAP0003's structured tag forms. This repository runsPSAP0005in its default strict mode since the Chipset r80 / Graphics r46 / BthPan r28 / NPU r24 release (psa-py-v4-llm-governance-strict); the originalpsap0005_relaxed_mode: truebaseline adopted at r76 has been retired and the key is omitted from.psa.config.json(see SPEC §A.13 Migration roadmap — statusCOMPLETED— and §D.34 for the retrospective).PSA2009(added in 3.8.0) is the static-analysis counterpart of the runtime defect that causedChipset r72 P05 -> FAILED with "WhqlCoSignAnalysis" property-not-found exceptionon a Japanese-locale Windows Server 2019 host.PSA2010/PSA2011(added in 3.9.0) would have caught the r75 §D.33 Defect A (Split-Pathbinder bug) and the §D.32.2Find-Signtoolfamily 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.
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:
-
Opts in to
PSAP0001,PSAP0002,PSAP0003,PSAP0004, andPSAP0005so 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 (PSAP0003forbids inline# rNN:tags;PSAP0004forbids in-scriptREVISION HISTORYblocks;PSAP0005in strict mode forbids any descriptiverNN-anchored prose in comment bodies — history lives inCHANGELOG.mdand design rationale inSPEC.mdPart D) are all enforced. -
Configures
PSA8001(cross-file function-body drift) withpsa8001_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. -
Disables
PSA4003(long line) because the pipeline scripts intentionally use multi-clause-fformat 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.ps1All 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.ps1For 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.
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.pychecks for, what regression testsTESTING.mdcovers, 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.
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.
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.
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.
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.
- INF File Sections and Directives
- INF Manufacturer Section (TargetOSVersion / ProductType)
- Differences in Driver Installation Between Server and Client SKUs
- Inf2Cat command reference
- SignTool command reference
- PnPUtil overview
- PnPUtil Command Syntax
- Windows Defender Application Control (WDAC) overview
- Deploy WDAC policies with script (CiTool)
- Windows Driver Kit (WDK) installation
- Windows Software Development Kit (SDK) downloads
- Driver signing requirements for Windows
- AMD Chipset Drivers (download)
- AMD Adrenalin Edition (download)
- AMD Ryzen AI Software (installation guide)
- AMD Ryzen AI Software (release notes)
- AMD Ryzen AI Software (supported configurations)
- AMD RyzenAI-SW (GitHub examples and source)
- AMD RyzenAI-SW (latest releases)
- TESTING.md — Physical-hardware validation results and the NPU script's far weaker validation status. English only.
- SPEC.md — Developer specification. English only.
- CHANGELOG.md — Chronological per-release change log. English only.
- CONTRIBUTING.md — How to contribute.
- README.ja.md — Japanese translation of this document, kept in sync.
psa.pycanonical location (ai-generated-artifacts) — PowerShell static analyzer used by this repository's CI gates.
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.
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.