The ticket said the fingerprint reader had stopped working on eleven ThinkPads. The change record said nothing had shipped that week.
Both statements were true. No task sequence ran, no application deployment landed, no cumulative update installed. And yet on 19 August a new driver package was staged into the driver store on every one of those machines, published as a fresh oem257.inf, and bound to hardware. Windows Update did it, quietly, in the ordinary course of a scan.
What makes this failure so expensive is not the driver. It is the forty minutes the team spends arguing about where it came from. One engineer swears drivers are blocked by Group Policy. Another blames the OEM's own update utility. A third points at the Intune driver update profile somebody built last quarter and never looked at again. All three are guessing, because none of them has looked at the one log on the device that records the answer in plain text.
Driver servicing has its own policy surface, its own delivery pipeline, its own staging area and its own log. It overlaps with quality updates but it is not the same thing, and the controls that govern it are not the controls most admins think they are. This post is about proving the delivery path before you change anything, because the same symptom has three completely different causes and each one needs a different fix.
A driver can reach a Windows device by at least three routes, and C:\Windows\INF\setupapi.dev.log labels every one of them in the section title. A Windows Update delivery opens a section literally titled Device Install (Install Windows Update driver), its cmd: line names wuaucltcore.exe out of C:\Windows\UUS, it carries a Flight Id, and its INF comes from C:\Windows\SoftwareDistribution\Download\Install. A driver riding inside a cumulative update opens Stage Driver Updates instead, is driven by TiWorker.exe, sources its INF from C:\Windows\WinSxS and scores Inbox rather than WHQL. A plug-and-play event opens Device Install (Hardware initiated) with no cmd: line at all. The policy that blocks the first route is ExcludeWUDriversInQualityUpdate under HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate — and on the real device measured for this post that value is absent, which means drivers were never blocked, whatever the runbook says. Read the log first. Then decide which policy you actually need.
The problem: a driver nobody approved, or one that never came
This failure arrives in two mirror-image forms, and both get misdiagnosed the same way.
The first form is the unwanted driver. A graphics driver, a docking-station firmware package, a fingerprint sensor driver or a modem configuration package appears on devices that nobody deployed it to. Something breaks. The change record is empty, so the team assumes an update went in and starts hunting through Get-HotFix output, which will never show it, because driver packages are not Component Based Servicing updates and do not appear there.
The second form is the missing driver. You built an Intune driver update profile, approved a version, and three weeks later half the fleet is still on the old one. Nothing failed. Nothing errored. The drivers simply were not offered, because a separate policy quietly told the client not to look.
Both forms produce the same investigative dead ends, and it is worth naming them so you stop walking into them.
| What the team tries first | What it actually tells you | Why it is a dead end |
|---|---|---|
Get-HotFix / the Windows Update history UI | Component Based Servicing updates only. On the measured device Get-HotFix returned four rows while the real package inventory held 121 installed and 95 staged packages. | Driver packages are not CBS packages. A driver that arrived from Windows Update may leave no trace in either view. |
The Microsoft-Windows-WindowsUpdateClient/Operational channel | That updates were found and downloaded. On the measured device: 368 Event 26 records, 69 Event 41 records, one Event 25. | Not one of those 438 event messages contains the word "driver". The channel confirms activity, never that the activity was a driver. |
| Device Manager driver date and version | What is bound to the device now. | Says nothing about who put it there or when it was staged. The staging and the binding are separate operations that can be days apart. |
| Checking whether a driver GPO "exists" | That a key is present. | A key can be present with zero values. The DriverSearching key on the measured device exists under CurrentVersion but the policy key of the same name does not exist at all. |
Resetting SoftwareDistribution | Nothing. | It deletes C:\Windows\SoftwareDistribution\Download\Install, which is the folder the log points at as the source of a Windows Update driver. You have just destroyed the corroborating evidence. |
wuauserv and bits, rename SoftwareDistribution, and reboot. Do not do that here, not yet. A Windows Update driver install records its source INF path as C:\Windows\SoftwareDistribution\Download\Install\<name>.inf. That folder is the single strongest corroborating artefact you have for "Windows Update did this", and it is the first thing the reset destroys. The setupapi log survives the reset, but the ability to cross-check the INF against the file that produced it does not. Read the log, copy it somewhere else, and only then consider touching the service.There is a third dead end that deserves its own paragraph because it is silent. Windows Update does not necessarily offer the newest driver. Microsoft is explicit: from Windows 10 version 1709, "Windows Update (WU) offers the best matching driver package, which is not necessarily the most recent". The selection considers hardware ID, date and version, and the critical/automatic/optional category, and it prioritises critical or automatic packages highest. The documented consequence is blunt: "an older critical driver package of otherwise equal value takes precedence over a newer optional driver package". If you are hunting for why a newer OEM driver never arrived, that sentence is often the whole answer, and no amount of client repair will change it.
Why it happens: driver servicing is its own policy surface
To diagnose this you need a working model of the pipeline. There are four stages and they fail independently.
Stage one is offering. The Windows Update client decides whether a driver update is applicable and whether it is allowed to look at all. This is where ExcludeWUDriversInQualityUpdate lives, and where an Intune driver update profile injects its approvals.
Stage two is download. The payload lands in C:\Windows\SoftwareDistribution\Download\Install as a loose INF plus its catalogue and payload files. Nothing is installed yet.
Stage three is staging. The driver package is copied into the driver store. Microsoft's own words: "The process of copying a driver package to the Driver Store is called staging. A driver package must be staged to the Driver Store before the package can be used to install any devices. As a result, driver staging and device installation are separate operations." Staging is where signature verification happens, where the package gets its oemNNN.inf published name, and where a device installation restriction policy gets its chance to say no.
Stage four is binding. Windows ranks every staged package that matches the hardware and installs the winner. This is the only stage where the driver actually changes what the device does, and it can happen minutes or days after staging.
DevicePath locations looking for something better. If it finds a better match, "Windows replaces the driver package it installed from the driver store with the better match". So the sequence a user experiences — device works, then device breaks twenty minutes later — is documented behaviour, not a fault. There is also a throttle worth knowing: from Windows 10 version 1703, if a matching package is already in the store when you plug a device in, "the system does not search Windows Update until the next regularly scheduled daily scan, which could be up to 24 hours". A driver that appears "the next morning" is that timer, not a coincidence.Now the policy surface. Three separate registry hierarchies control three different stages, they are documented in three different places, and confusing them is the single most common reason a driver block "does not work".
| Value | Meaning | What to look for |
|---|---|---|
WindowsUpdate\ExcludeWUDriversInQualityUpdate (REG_DWORD) | 0 (default) allows Windows Update drivers, 1 excludes them. Group Policy name: "Do not include drivers with Windows Updates", under Windows Components > Windows Update > Manage updates offered from Windows Update. ADMX file WindowsUpdate.admx. | Absence is the finding. If the value is not there, the default applies and drivers are allowed. Do not report "the policy is not set to 1" as "drivers are blocked". This is the value the Intune update ring's Windows drivers Allow/Block setting writes. |
WindowsUpdate\SetPolicyDrivenUpdateSourceForDriverUpdates (REG_DWORD) | 0 = detect, download and deploy driver updates from Windows Update. 1 (default) = from WSUS. | Only meaningful alongside an intranet update service. If you run WSUS and never sync the Drivers classification, the default of 1 means devices get no drivers at all and no error to explain it. |
DeviceInstall\Restrictions\DenyDeviceIDs | List of Plug and Play hardware IDs and compatible IDs Windows is prevented from installing. GP name "Prevent installation of devices that match any of these device IDs". | The surgical block. By default this "takes precedence over any other policy setting that allows Windows to install a device". |
DeviceInstall\Restrictions\DenyInstanceIDs | List of device instance IDs to block. GP name "Prevent installation of devices that match any of these device instance IDs". | Instance IDs are per-device, not per-model. Useful for one broken lab machine, wrong for a fleet rule. |
DeviceInstall\Restrictions\DenyDeviceClasses | List of device setup class GUIDs whose driver packages Windows is prevented from installing or updating. | Blunt but effective for a whole class. Note that many modern driver packages report class Extension, GUID {e2f84ce7-8efa-411c-aa69-97454ca4cb57} — blocking that class blocks a great deal you did not intend. |
DeviceInstall\Restrictions\AllowDeviceIDs, AllowInstanceIDs, AllowDeviceClasses | The matching allow lists. | Documented as "intended to be used only when" the layering policy is enabled. An allow list on its own usually does nothing you expect. |
DeviceInstall\Restrictions\DenyUnspecified | "Prevent installation of devices not described by other policy settings" — the legacy default-deny switch. | Microsoft says this "has been replaced by" the layering policy. If both are set, the layering policy wins "and the other policy setting will be ignored". |
DeviceInstall\Restrictions\AllowDenyLayered | "Apply layered order of evaluation for Allow and Prevent device installation policies across all device match criteria". Establishes the hierarchy: device instance IDs > device IDs > device setup class > removable devices. | Without this, the documented default is that "all Prevent installation policy settings have precedence over any other policy setting that allows Windows to install a device". Every allow-list design that "mysteriously fails" is missing this value. |
DriverSearching\ (key) | The registry key that backs "Specify search order for device driver source locations" (DriverSearchPlaces_SearchOrderConfiguration, ADMX file DeviceSetup.admx). | Microsoft's Policy CSP reference names the key but does not publish the registry value name. Set it through the ADMX, and audit it by reading the key's values rather than by asserting a name you have not verified. |
That last row is not pedantry, and here is why it matters. On the device measured for this post the policy key HKLM\SOFTWARE\Policies\Microsoft\Windows\DriverSearching does not exist. But a key with the same leaf name does exist somewhere else entirely, and it holds a value:
| Value | Meaning | What to look for |
|---|---|---|
DevicePath (REG_EXPAND_SZ) | The preloaded driver search locations. Microsoft documents the default as %SystemRoot%\INF. Windows searches here after the initial driver-store install, alongside Windows Update. | Measured value on the device: C:\WINDOWS\inf, type ExpandString. Extra paths appended here are a supported and frequently forgotten driver injection route. If a driver appears and no policy explains it, read this value. |
DriverSearching\SearchOrderConfig (REG_DWORD) | Measured on the device as 1. This is not the policy location and I could find no Microsoft reference documentation for the value name — community sources only. | Do not build a compliance check on it, and do not report its presence as "a driver policy is configured". It sits outside \Policies\, so it is a machine preference, not a managed setting. Report it as observed state, flagged as undocumented. |
ExcludeWUDriversInQualityUpdate. So the classic self-inflicted wound is an update ring built in 2021 with drivers blocked, plus a shiny driver update profile built in 2025 that approves drivers nobody will ever receive. The profile reports approvals happily. The devices never see them. Nothing errors.The Intune driver update profile itself deserves a clear-eyed summary, because its behaviour is unusual and mostly documented in one place. It offers two approval methods that cannot be changed after creation: "Manually approve and deploy driver updates", where every new update lands as Needs review, and "Automatically approve all recommended driver updates", where recommended updates land as Approved and everything else lands on an other drivers list as Needs review. Automatic approval requires a deferral, "Make updates available after (days)", which "supports from zero to 30 days and starts from the day the update is added to the policy, not from the date the update was made available or published by the OEM".
Four statuses exist — Needs review, Approved, Declined, Paused — and the transitions are one-way in places: "After an update is Approved, it can never be Declined, but you can Pause it indefinitely." Pausing has a documented side effect people are routinely surprised by: pause the newest approved version and "Windows Update begins to install that older version on applicable devices", because an earlier approved version is still approved and still applicable.
Three more documented facts will save you a wasted afternoon. First, "Intune doesn't collect an inventory of installed drivers" — the driver list in the policy is a list of what could be installed, not what is. Second, "policies for Windows driver updates don't support options to remove or roll-back driver updates" — there is no undo button in the portal, which is exactly why the rollback section below is on-device. Third, and this one is a genuine trap for OEM-managed fleets: "Windows driver update policies don't enforce Computer Hardware ID (CHID) targeting defined by OEMs, even when those drivers are listed as recommended. As a result, managed devices can receive newer recommended driver versions instead of CHID-targeted drivers."
How to verify: prove the delivery path before you touch policy
Everything above is context. This section is the actual work, and it is almost entirely reading rather than running.
The log you want is the device installation text log. Microsoft documents it as SetupAPI.dev.log, an ANSI plain text file "located by default in the %SystemRoot%\inf directory", written by the Plug and Play manager and SetupAPI. It is a sectioned log: each section "records the events during a single device installation", with a header, a body of prefixed entries and a footer.
And the section titles are the delivery-path taxonomy. That is the whole trick. Here is the real census from the current log on the measured device — 273 sections in 48,837 lines.
Read that list as a source attribution table rather than a list of operations. Install Windows Update driver is Windows Update. Stage Driver Updates is the servicing stack, which is how drivers arrive inside a cumulative update. DrvSetupInstallDriver and Setup Import Driver Package are a setup program or a tool driving the driver store directly, which is where an OEM utility, a ConfigMgr package or somebody's pnputil script shows up. DiInstallDriver and UpdateDriverForPlugAndPlayDevices are the two documented APIs an installer calls, so those are an application. Hardware initiated is a device being plugged in.
!!! lines is not proof of health, and 890 warnings is not proof of illness — the real warnings on this device were things like ! dvi: Query-and-Remove failed: 0x05: CR_INVALID_DEVNODE. and ! inf: Using WDF schema version 2.23 when section requires version 2.25. on a machine with no reported driver problem at all. Judge the outcome, which the log states explicitly as Outcome - Imported and <<< [Exit status: SUCCESS], never a grep count.Now the centrepiece. Here is a real, complete Windows Update driver delivery, captured read-only from the live device. Every line is genuine.
There are seven independent proofs of provenance in that one section, and any two of them are enough to close the argument.
The section title says Install Windows Update driver in plain English. The cmd: line names the process: wuaucltcore.exe, out of C:\Windows\UUS\AMD64, loading UpdateDeploy.dll as its deployment handler. The Flight Id is a Windows Update construct; nothing else emits one. The INF path is C:\Windows\SoftwareDistribution\Download\Install, which is the Windows Update download staging area and nowhere else. The Signer Score of 0x0D000005 (WHQL) plus a Submission ID means this package went through the Hardware Dev Centre, which is a precondition for Windows Update distribution. The timestamp gives you the exact second to correlate against your update rings. And the published name oem257.inf gives you a handle for every subsequent command.
One detail in that block is worth pausing on because it trips up inventory scripts: inf: Provider = Lenovo on a driver package called AmdMepEnum.inf. The Provider string is authored by whoever published the package, not by whoever made the silicon. Grouping a driver inventory by Provider will scatter one vendor across several buckets, and on this device it does exactly that — pnputil reports 30 packages from Advanced Micro Devices, Inc. and a further 10 from Advanced Micro Devices, Inc without the trailing period. Two strings, one vendor, and any report that groups on that column is wrong.
Now the contrast case, so you can tell the routes apart at a glance.
That is the discriminator, in one table:
| Delivery path | Section title | The cmd: line | INF source and signer |
|---|---|---|---|
| Windows Update (including Intune driver update profile approvals, which are delivered by Windows Update) | Device Install (Install Windows Update driver) | wuaucltcore.exe from C:\Windows\UUS\<arch>, with UpdateDeploy.dll | SoftwareDistribution\Download\Install; WHQL (0D000005) plus a Submission ID; a Flight Id is present |
| Inside a cumulative update / servicing stack | Stage Driver Updates, Install Driver Updates, Unstage Driver Updates | TiWorker.exe from the versioned WinSxS servicing-stack directory | C:\Windows\WinSxS\...; Inbox (0D000003); no Submission ID, no Flight Id; files hardlinked |
OEM tool, ConfigMgr package, or a script calling pnputil / DISM | Driver Install (DrvSetupInstallDriver), Setup Import Driver Package | The installer's own executable path — read it, it names the culprit | Wherever the installer unpacked to; signer varies |
| An application calling the install APIs | Device Install (DiInstallDriver), Device Install (UpdateDriverForPlugAndPlayDevices) | The calling application | Application-supplied |
| Plug and play, from packages already staged | Device Install (Hardware initiated) | None. The absence of a cmd: line is itself the signature | Driver store only; nothing is downloaded |
The hardware-initiated case has its own payoff, because it is where you see the ranking decision that actually chose the driver. This block is what "prove which driver won and why" looks like:
That Flight IDs field is the single most under-used forensic artefact in Windows driver servicing. It appears on the driver node, it survives in the log, and it tells you a specific staged package arrived through a Windows Update flight even when the install section that staged it has long since rotated out of the current log.
-like to find section starts. Where-Object { $_ -like '>>> [*' } returns 0 on a log with 273 sections, because in PowerShell wildcard syntax an unescaped [ opens a character class and the pattern never terminates. Measured on the same file in the same session: -like '>>> [*' gave 0, while -match '^>>> \[' gave 273 and Select-String -SimpleMatch '>>> [' gave 273. A silent zero is far worse than an error here, because "no driver installs found" is a perfectly plausible-looking wrong answer. Use -match with an escaped bracket, or Select-String -SimpleMatch, and always sanity-check the count against the number of Section start lines.Two more things about the log itself before we move on. It rotates by size, at roughly five megabytes, into archives named setupapi.dev.YYYYMMDD_HHMMSS.log in the same folder. On the measured device the current log was 3,935,513 bytes and there were six archives ranging from 4.27 MB to 5.34 MB, going back to September 2025 — nearly a year of driver history that most people never open. And there are siblings: Microsoft documents SetupAPI.app.log for "installation operations other than those that pertain specifically to device and driver installations", and on this device there were also setupapi.offline.log, setupapi.upgrade.log and setupapi.setup.log present, which the current documentation does not describe. Treat those three as observed rather than documented, and read them for the upgrade path only.
The entry prefixes are documented and worth memorising, because they are the only severity signal in the file: "!!! " is "an error message in a text log", "! " is a warning, and a leading space or " . " is informational. The category tag after the prefix tells you which subsystem spoke. Microsoft publishes a table of these, and as with the Windows Update trace tags, the published table is incomplete. Documented: bak, cci, cpy, dvi, flq, inf, ndv, prp, reg, set, sig, sto, ui, ump. Also present in the real log on this device and not in that table: idb (5,044 lines), utl (2,370), pol (611), dvs (605) and cmd (160). If you build a parser against the documented list you will discard the driver-database, driver-selection, policy-check, driver-setup and command-line lines — which is to say, exactly the lines that answer the question.
The decision path
Work these in order. Stop at the first step that gives you a definite answer.
- Copy the log before anything else.
Copy-Item C:\Windows\INF\setupapi.dev.logplus everysetupapi.dev.2*.logarchive to a share. Everything after this is non-destructive, but a reboot, a rotation or a well-meaning colleague'sSoftwareDistributionreset can cost you the evidence. - Identify the package. From Device Manager, or better
pnputil /enum-drivers, get thePublished Name(oemNNN.inf),Original Name,Provider NameandDriver Version. The published name is your search key for everything below. - Find the staging event. Search the current log and the archives for the original INF name. You are looking for the
{Core Driver Package Import: ...}line and thePublished '<pkg>' to '<oemNNN.inf>'line. The section header above it names the delivery path. If you get a hit, you are done: the section title is your answer. - If the section title is
Install Windows Update driver, confirm with theFlight Idand theSoftwareDistribution\Download\Installpath, then go to step 7. This is Windows Update, and the question becomes which policy allowed it. - If the section title is
Stage Driver UpdatesorInstall Driver Updates, the driver came in a cumulative update viaTiWorker.exe. Driver policy is irrelevant. Your lever is the LCU, notExcludeWUDriversInQualityUpdate. - If the section title names a setup or an API (
DrvSetupInstallDriver,Setup Import Driver Package,DiInstallDriver,UpdateDriverForPlugAndPlayDevices), read thecmd:line. It contains the full path of the process that did it. That is your OEM utility, your ConfigMgr package or your own script, and no Windows Update policy will ever stop it. - Read the actual policy state, not the intended policy state. Query
HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdateforExcludeWUDriversInQualityUpdateand report present with value or absent, never a bare boolean. Then check...\DeviceInstall\Restrictionsfor existence and value count. An absent value means the documented default, and for this policy the documented default is that drivers are allowed. - Only if steps 3 to 6 all came up empty, look at the alternate injection routes: extra paths in
DevicePath, and the count ofDevice Installation Restrictions Policy Checksections, which on this device was 109 — proof the policy evaluation ran, not proof that any policy was configured.
Step seven is where most investigations should have started, and it is short enough to run inline. This is the real output from the measured device.
Note the policy pin while you are here, because it is a nice illustration of why you read state rather than intent: TargetReleaseVersionInfo says 24H2 while the installed release is 25H2, build 26200.9168. The device is running a later release than the one it is pinned to, because the 25H2 enablement package (KB5054156) overtook the pin back in February. A stale pin is invisible until you compare it against installed state, and exactly the same reasoning applies to a stale driver policy.
Reading the driver store
The driver store is where staged packages live, and its structure is the second half of the evidence. Microsoft's conceptual doc describes it as "a trusted collection of inbox and non-Microsoft driver packages" maintained "in a secure location on the local hard disk", and states the rule that matters: "Only the driver packages in the Driver Store can be installed on a device."
The path is documented by example in the SetupAPI reference, which walks through a package whose INF lands as OEM1.inf in C:\Windows\inf and whose driver-store copy lands at C:\windows\system32\driverstore\filerepository\myinf_12345678\myinf.inf. That is the same doc that states the dual-copy rule explicitly: "Device installation installs one copy in the system INF directory and assigns that copy of the INF file a unique published file name of the form OEMnnn.inf. Device installation installs a second copy of the INF file in the driver store and assigns that copy the original INF file name."
On a modern build the folder name carries an architecture token that the doc's example predates. Measured folder names on this device: 1394.inf_amd64_ff5c4e8141fc4520, acpi.inf_amd64_46de00f00114863a, amdmepenum.inf_amd64_47f7dbbdfa86ef26. So the real shape is <original-inf-name>.inf_<arch>_<hash>. Do not hardcode it — Microsoft's own guidance is that paths into the store "shouldn't be hardcoded as they can be different between different versions of the driver package, different OS versions, different OS editions".
That 262-versus-990 gap is documented behaviour, not a discrepancy: pnputil "lists only driver packages that aren't in-box packages. An in-box driver package is one that's included in the default installation of Windows or its service packs." The exact match between 262 Published Name entries and 262 oem*.inf files in C:\Windows\INF is the dual-copy rule proving itself on a live machine, and it gives you a fast integrity check: if those two numbers ever diverge, your driver database and your INF directory have drifted.
The binaries behind all of this are worth naming, because half of them are not where people assume.
| File | Where it actually lives | Version / description on the measured device | Role in this investigation |
|---|---|---|---|
wuaucltcore.exe | C:\Windows\UUS\AMD64 — not System32 | 1509.2607.1012.0, "Windows Update" | The process named on the cmd: line of every Windows-Update-delivered driver install. Its presence in that line is the provenance proof. |
UpdateDeploy.dll | C:\Windows\UUS\AMD64 | 1509.2607.1012.0, "Windows Update Deployment Engine" | Passed as /DeploymentHandlerFullPath. This is the component that actually drives the driver deployment. |
TiWorker.exe | The versioned WinSxS servicing-stack component directory — not C:\Windows\servicing | "Windows Modules Installer Worker" | The cmd: line for Stage Driver Updates. Seeing this instead of wuaucltcore.exe tells you the driver rode in on a cumulative update. |
pnputil.exe | C:\Windows\System32, in every Windows since Vista | 10.0.26100.8972, "Microsoft PnP Utility - Tool to add, delete, export, and enumerate driver packages." | The read-only inventory tool, and the documented removal tool. |
drvstore.dll | C:\Windows\System32 | 10.0.26100.8972, "Driver Store API" | The driver store implementation. Versioned with the servicing stack, not with the OS build (26100 stack on a 26200 build is normal). |
setupapi.dll | C:\Windows\System32 | 10.0.26100.1, "Windows Setup API" | Writes the text logs you have been reading, via the documented SetupAPI logging functions. |
newdev.dll | C:\Windows\System32 | 6.0.5054.0, "Add Hardware Device Library" | Exports DiRollbackDriver, DiInstallDriver and DiUninstallDriver. When you see Device Install (DiInstallDriver) in the log, this DLL is what ran. |
wuaueng.dll | C:\Windows\System32 | 1509.2607.1012.0, "Windows Update Agent" | The wuauserv service DLL. Note it shares the UUS version, not the OS version — the agent is serviced separately from the build. |
The event log, and its limits
Event logs are the weakest link in driver diagnosis, and it is important to know that up front so you do not waste a day building a detection on them. Here is what the System channel actually contained over a 30-day window on the measured device, out of 18,630 events.
| Event ID | Message (real, captured) | What it tells you |
|---|---|---|
20003Microsoft-Windows-UserPnp, Information | "Driver Management has concluded the process to add Service Intel(R) Broadband Manager Service for Device Instance ID SWD\MBFW\{...} with the following status: 0." | A driver's service was registered against a device instance. Status 0 is success. Observed 5 times in 30 days. This is the closest thing to a "a driver was installed" event, and it fires per service, not per package. |
219Microsoft-Windows-Kernel-PnP, Warning | "The driver \Driver\WUDFRd failed to load. Device: USB\VID_27C6&PID_6594\... Status: 0xC0000365" | A user-mode driver framework reflector could not load for a device. Observed 240 times. High volume and benign on this machine — do not alert on it without a device-level baseline. |
225Microsoft-Windows-Kernel-PnP, Warning | "The application ...\mpextms.exe with process id 54876 stopped the removal or ejection for the device SCSI\Disk&Ven_NVMe&Prod_SAMSUNG_MZVL21T0\..." | Something held a device open during a removal attempt. 1,738 occurrences, all from Defender. Noise, not a driver failure. |
10118Microsoft-Windows-DriverFrameworks-UserMode, Information | "UMDF reflector is unable to connect to service control manager (SCM). This is expected during boot, when SCM has not started yet. Will retry when it starts." | The message says "expected" in its own text. 240 occurrences. A perfect example of an event that looks alarming in a dashboard and means nothing. |
A second channel is more useful than most people realise, and it is off most teams' radar entirely.
| Event ID | Message (real, captured) | What it tells you |
|---|---|---|
30 | "Device container {00000000-0000-0000-ffff-ffffffffffff} is queued for setup." | Device Setup Manager has picked up a container. 456 occurrences in 2,131 records read. |
112 | "Device container 'WKSTN-01' ({...}) has been serviced, processed 8 tasks, and wrote 60 properties in 1650 ms." | A servicing pass completed against a container, with a task and property count. 521 occurrences. This is the closest thing to a "metadata and driver servicing ran" receipt. |
190 | "Property heuristics for device container 'WKSTN-01' ({...}) completed in 394 ms." | Property heuristics finished. 527 occurrences — the highest-volume ID in the channel. |
11 | "DSM service is idle and waiting for stop." | The Device Setup Manager service went idle. 159 occurrences. Useful only as a bracket around activity. |
The companion Microsoft-Windows-DeviceSetupManager/Operational channel held 225 records with just two IDs: 300, "Device container '{...}' has entered the ready state" (199 occurrences), and 301, "Device setup for device container '{...}' has been completed" (26 occurrences).
Microsoft-Windows-UserPnp, Microsoft-Windows-Kernel-PnP or Microsoft-Windows-DeviceSetupManager. Every ID and message above is a real capture from a live device, not a documented contract, and Microsoft can change any of them. The sibling 20001 event that community threads describe as "Driver Management concluded the process to install driver ... with the following status" did not appear at all in the 30-day window on this machine. Build your primary detection on setupapi.dev.log, which is documented, and treat these events as corroboration only.The fix: block the right route, roll back the right way
By this point you know which of the five delivery paths installed the driver. The fix follows from that, and only from that. Applying the wrong one is how teams end up with three overlapping driver policies and a fleet that behaves unpredictably.
If the route was Windows Update and you want to stop all of it, the lever is ExcludeWUDriversInQualityUpdate set to 1. Group Policy: "Do not include drivers with Windows Updates", under Windows Components > Windows Update > Manage updates offered from Windows Update. Intune: the update ring's Windows drivers setting, or the same CSP through the settings catalog. Understand what you are buying: this is fleet-wide and it excludes drivers from quality updates entirely, which also means it disables the Intune driver update profile you may be relying on. Microsoft's own prerequisite list for driver update policies says so in as many words.
If the route was Windows Update and you want to stop exactly one driver, do not use the exclusion policy. Use a device installation restriction: PreventInstallationOfMatchingDeviceIDs, which writes DenyDeviceIDs under Software\Policies\Microsoft\Windows\DeviceInstall\Restrictions. Take the hardware ID straight out of the dvi: Searching for hardware ID(s): lines in the log — they are already in the exact form the policy wants. Two details from the documentation: multiple entries are delimited with &#xF000; in SyncML, and setting DeviceInstall_IDs_Deny_Retroactive to true applies the block to matching devices that are already installed, which is usually what you want in an incident.
[Device Installation Restrictions Policy Check] section. On the measured device that section appeared 109 times — and remember what that means: the check ran 109 times. It does not mean a restriction was configured, because on that device the restrictions key does not exist. Presence of the section proves evaluation. Only the registry proves configuration.If the route was an OEM tool, ConfigMgr, or a script, no Windows Update policy will help and no device installation restriction is the natural fix either. The cmd: line named the executable. Go and deal with that executable: uninstall the OEM update utility, fix the ConfigMgr deployment, or find whoever wrote the pnputil /add-driver /install line in a task sequence. This is the single most common misattribution in the whole topic, and it is also the easiest one to settle, because the log literally prints the full path of the offending process.
If the route was a cumulative update, your lever is update deployment, not driver policy. Nothing in the driver policy surface controls what a servicing-stack-staged package does.
Rolling one back, safely
Now the part people get wrong. There are two different operations here and they are not interchangeable.
Rollback restores the previous driver on a device. It is implemented by DiRollbackDriver in newdev.dll, and it is what Device Manager's Roll Back Driver button on the Driver tab calls. Read the constraints from the API documentation before you promise anyone this will work:
- "Windows maintains at most one backup driver for a device." One. Not a history.
- Windows sets the backup "immediately after the driver is successfully installed on the device and Windows determines that the device is functioning correctly" — so if the bad driver installed badly, or the device did not come up healthy, there may be no backup at all. The failure is
ERROR_NO_MORE_ITEMS, documented as "A backup driver is not set for the device." - Rollback installs the backup "whether the backup driver is a better match for the device than the driver that is currently installed". It ignores ranking. That is the point, and it is also why a plug-and-play cycle can undo your rollback if the newer package is still staged.
- And the part that catches people: "If the driver that is replaced by the backup driver is not an inbox driver and is not installed on any other devices in the system,
DiRollbackDriverremoves the driver from the system." A rollback can silently delete the package you were about to send to the vendor for analysis. - It requires administrator rights, and a 32-bit caller on a 64-bit system fails with
ERROR_IN_WOW64.
Removal takes the package out of the driver store so it can never be selected again. The documented tool is pnputil:
The ordering in that block is deliberate. Export before delete, always. Microsoft is explicit about why /uninstall matters rather than a bare delete: DiUninstallDriver and pnputil /delete-driver <oem#.inf> /uninstall "will first update any devices using the driver package being removed to no longer be installed with that driver package before attempting to remove the driver package". A force delete of a package whose files run from the driver store would leave devices pointing at files that no longer exist — which is precisely why force removals "aren't allowed for driver packages that have any files that are 'run from Driver Store'".
ExcludeWUDriversInQualityUpdate is absent or 0, and no device installation restriction covers the hardware ID, then the next scan will offer it again — and on a device you just cleaned, it will now be the best available match. The sequence that actually holds is: put the block in place and confirm it applied, then export, then delete, then roll back or reinstall the known-good version. Delete-first is how a fleet ends up flapping between two driver versions for a fortnight. And if you are on Intune driver update profiles, remember there is no portal-side undo: "policies for Windows driver updates don't support options to remove or roll-back driver updates." Pausing stops future deployment; it does not touch a completed install.Proof it worked: a real driver-provenance audit
The point of all this is to be able to answer, on demand, for any driver on any device: what is it, where did it come from, when, and which policy allowed it. Here is that audit as a read-only pass, with the real numbers from the measured device so you know what a clean result looks like.
That last line is the whole post. The outcome of a good driver investigation is very often "the policy you thought you had, you never had" — and that is a documentation fix, not a device fix. It is also the only conclusion you cannot reach by guessing.
Turn the audit into something that runs unattended and you change the economics of the next incident. Four artefacts are enough. Ship pnputil /enum-drivers output per device, keyed on hostname and OS build, so you have a driver inventory Intune does not collect. Ship the count and titles of setupapi.dev.log sections per delivery path, so a spike in Install Windows Update driver shows up as a signal rather than a ticket wave. Ship the presence-or-absence of the four policy values in the registry tables above, as three-state data — present-and-set, present-and-zero, absent — never a boolean. And copy the rotated setupapi.dev.*.log archives off the device before they age out, because eleven months of driver provenance is worth more than the disk it occupies.
Do that and the next time somebody says a driver broke the fleet, you will not be arguing about where it came from. You will be reading the section title.
References
- Policy CSP - Update -
ExcludeWUDriversInQualityUpdate: the GP English name "Do not include drivers with Windows Updates", the allowed values, theSoftware\Policies\Microsoft\Windows\WindowsUpdateregistry key and value name, theWindowsUpdate.admxmapping, andSetPolicyDrivenUpdateSourceForDriverUpdates. - How Windows selects a driver package for a device - the two-phase model, the
DevicePathregistry value and its%SystemRoot%\INFdefault, the 1703 24-hour scan throttle, and the "best matching driver package, which is not necessarily the most recent" rule with the critical/automatic/optional precedence. - Driver Store - the definition of staging, the rule that only packages in the store can be installed, the catalogue and signature requirements, and the prohibition on modifying store contents out of band.
- PnPUtil Command Syntax - every command and flag verbatim, including
/enum-drivers [/class] [/files],/export-driver,/delete-driver [/uninstall] [/force] [/reboot],/enum-devices ... /drivers, and the note that PnPUtil will not force a driver that is not the highest ranked. - PnPUtil Command Line Tool for Driver Packages - the
%windir%\system32location, and the statement that the tool lists only driver packages that aren't in-box packages. - SetupAPI Text Logs - SetupAPI.dev.log versus SetupAPI.app.log, the
%SystemRoot%\infdefault location, and the header/section/entry structure. - Format of a Text Log Section - the section header, body and footer format, and the worked
Device Installexample. - Format of a Text Log Section Body - the entry-prefix severity table and the published event-category tags (
dvi,inf,sto,sig,flq,cpy,umpand the rest), plus the{Build Driver List}andRankexample. - Format of Log Entries That Are Not Part of a Text Log Section - the exact meaning of the
"!!! ","! "and" . "prefixes, and the 336-character entry limit. - SetupAPI Logging Registry Settings - the global event level and event category model, and the confirmation that the text logs live in
%SystemRoot%\Infby default. - Policy CSP - DeviceInstallation - the full allow/deny set with the exact
Software\Policies\Microsoft\Windows\DeviceInstall\Restrictionsvalue names, the layered-evaluation hierarchy, the retroactive flags, and thesetupapi.dev.logverification snippet Microsoft supplies for each one. - Policy CSP - ADMX_DeviceSetup - "Specify search order for device driver source locations" (
DriverSearchPlaces_SearchOrderConfiguration), itsSoftware\Policies\Microsoft\Windows\DriverSearchingkey, and theDeviceSetup.admxmapping. - Manage Windows driver updates with Microsoft Intune - the architecture (Intune approvals, Autopatch orchestration, Windows Update delivery), the licensing and telemetry prerequisites, and the
wlidsvcrequirement. - Configure Windows driver update policies - the two approval methods, the 0-30 day "Make updates available after (days)" deferral, the four statuses and their one-way transitions, the recommended-versus-other-drivers split, the pause-falls-back-to-older-version behaviour, the CHID caveat, and the statement that these policies don't support removal or rollback.
- Windows update ring settings in Intune - the Windows drivers Allow/Block setting and its explicit mapping to
ExcludeWUDriversInQualityUpdate. - DiRollbackDriver function - "Windows maintains at most one backup driver for a device", when a backup is and is not set,
ERROR_NO_MORE_ITEMS, and the behaviour of removing the replaced driver from the system. - SetupGetInfDriverStoreLocation function - the dual-copy rule, the
OEMnnn.infpublished-name convention, and the workedC:\windows\system32\driverstore\filerepository\...path example. - Run from Driver Store - why driver store paths must not be hardcoded, and why force removal is refused for packages with run-from-Driver-Store files.