HomeNewsletterCommunityMVP FeedToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog
Windows Update Windows UpdateDriverssetupapi.dev.logpnputilDriver StoreIntuneGroup PolicyWindows 11

A driver arrived from Windows Update and broke a fleet: how to prove which policy let it through

IA
Imran Awan
23 August 2026

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.

The short version

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 firstWhat it actually tells youWhy it is a dead end
Get-HotFix / the Windows Update history UIComponent 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 channelThat 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 versionWhat 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 SoftwareDistributionNothing.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.
Watch out: the reflex fix for anything Windows Update shaped is to stop 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.

Context: the two-phase model matters more than it looks. Microsoft documents that Windows "installs the best matching driver package in the driver store, allowing the device to begin operation quickly", and only after that goes to Windows Update and the 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".

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows
ValueMeaningWhat 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\DenyDeviceIDsList 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\DenyInstanceIDsList 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\DenyDeviceClassesList 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, AllowDeviceClassesThe 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:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
ValueMeaningWhat 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.
Gotcha: the Intune driver update policy documentation contains a prerequisite that silently defeats the whole feature, and it points straight back at the registry table above. Before creating a driver update policy Microsoft tells you to check two things: in a Windows update ring, "Ensure the Windows driver setting is set to Allow", and in a settings catalog policy, "In the Windows Update client policies category, ensure that Exclude WU Drivers in Quality Update is set to Allow Windows Update drivers". Both of those write the same CSP: 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.

Section-title census — C:\Windows\INF\setupapi.dev.log
# Real counts, current log only (rotated archives hold more). # $L = Get-Content 'C:\Windows\INF\setupapi.dev.log' -ReadCount 0 Count Section title ----- ------------- 109 Device Installation Restrictions Policy Check 70 Delete Device 34 Driver Install (DrvSetupInstallDriver) 28 Uninstall device subtree 6 Enable Device Install 6 Device Install (Install Windows Update driver) <-- Windows Update 4 Device Install (Hardware initiated) <-- plug-and-play 2 Uninstall Driver Updates 2 Stage Driver Updates <-- servicing stack 2 Install Driver Updates 2 Disable Device Install 2 Unstage Driver Updates 1 Driver Uninstall (DrvSetupUninstallDriver) 1 Device Install (UpdateDriverForPlugAndPlayDevices) 1 Driver Uninstall (DiUninstallDriver) 1 Restart Device 1 Setup Import Driver Package 1 Device Install (DiInstallDriver) # 546 lines begin with '>>>' and 546 with '<<<' - perfectly paired. # That is 273 title lines + 273 'Section start' lines, and the same closing. # Error lines ('!!!'): 0. Warning lines ('! '): 890.

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.

Tip: note the zero error lines against 890 warnings. This is the same trap as CBS.log, and it goes both ways. A driver install that shows no !!! 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.

setupapi.dev.log — a driver delivered by Windows Update, 19 Aug 2026
>>> [Device Install (Install Windows Update driver) - pci\ven_1022&dev_1502&subsys_50d817aa] >>> Section start 2026/08/19 16:06:19.456 cmd: "C:\WINDOWS\uus\AMD64\wuaucltcore.exe" /DeploymentHandlerFullPath \\?\C:\Windows\UUS\AMD64\UpdateDeploy.dll /ClassId 2eb1f6b0-286b-4fa2-85e1-d5830450d313 /RunHandlerComServer dvs: Flight Id = RD:123A90 dvs: Recovery Id = 8251ebb2-8fc2-4c5c-9050-610700bd52eb dvs: INF path: C:\WINDOWS\SoftwareDistribution\Download\Install dvs: Found 1 driver updates under 'C:\WINDOWS\SoftwareDistribution\Download\Install'. 16:06:19.461 dvs: {Driver Setup Import Driver Package: ...\Download\Install\AmdMepEnum.inf} 16:06:19.466 ump: Import flags: 0x00000001 pol: {Driver package policy check} 16:06:19.609 pol: {Driver package policy check - exit(0x00000000)} 16:06:19.611 sto: {Stage Driver Package: ...\Download\Install\AmdMepEnum.inf} 16:06:19.613 inf: Provider = Lenovo inf: Class GUID = {e2f84ce7-8efa-411c-aa69-97454ca4cb57} inf: Driver Version = 09/23/2025,32.1.0.102 inf: Catalog File = AmdMepEnum.cat inf: {Query Configurability: ...} 16:06:19.637 inf: Driver package is fully isolated. sig: Driver package catalog is valid. sig: Success: File is signed in catalog. sig: Signer Score = 0x0D000005 (WHQL) sig: Signer Name = Microsoft Windows Hardware Compatibility Publisher sig: Submission ID = 29997810_14393630452944201_1152921505699883615 sto: {Core Driver Package Import: amdmepenum.inf_amd64_47f7dbbdfa86ef26} 16:06:19.762 cpy: Target Path = C:\WINDOWS\System32\DriverStore\FileRepository\amdmepenum.inf_amd64_47f7dbbdfa86ef26 idb: Created driver package object 'amdmepenum.inf_amd64_47f7dbbdfa86ef26' in SYSTEM database node. idb: Created driver INF file object 'oem257.inf' in SYSTEM database node. idb: Registered driver package 'amdmepenum.inf_amd64_47f7dbbdfa86ef26' with 'oem257.inf'. idb: Activating driver package 'amdmepenum.inf_amd64_47f7dbbdfa86ef26'. cpy: Published 'amdmepenum.inf_amd64_47f7dbbdfa86ef26\amdmepenum.inf' to 'oem257.inf'. idb: Indexed 11 device IDs for 'amdmepenum.inf_amd64_47f7dbbdfa86ef26'. sig: Installed catalog 'AmdMepEnum.cat' as 'oem257.cat'. dvs: Driver Package: dvs: Outcome - Imported dvs: Driver INF - amdmepenum.inf (oem257.inf) dvs: Driver Version - 09/23/2025,32.1.0.102 dvs: {Driver Setup Import Driver Package - exit (0x00000000)} 16:06:20.144

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.

setupapi.dev.log — the same operation, but driven by the servicing stack
>>> [Stage Driver Updates] >>> Section start 2026/08/07 12:11:27.743 cmd: C:\WINDOWS\winsxs\amd64_microsoft-windows-servicingstack_31bf3856ad364e35_10.0.26100.8872_none_a4fce299776b787f\TiWorker.exe -Embedding sto: Image State = Specialized sto: Image OS Version = 10.0.26200 sto: Driver Updates = 1 sto: {Stage Driver Package: C:\WINDOWS\WinSxS\amd64_dual_wpcip.inf_31bf3856ad364e35_10.0.26100.8521_none_59d43bce6b5a26df\wpcip.inf} 12:11:27.781 inf: Provider = Microsoft inf: Driver Version = 06/21/2006,10.0.26100.8521 sig: Signer Score = 0x0D000003 (Inbox) sto: {Core Driver Package Import: wpcip.inf_amd64_868c60ecf2281121} 12:11:27.797 flq: Hardlinking '...\WinSxS\...\pcip.sys' to '...\DriverStore\FileRepository\wpcip.inf_amd64_868c60ecf2281121\pcip.sys'. flq: Hardlinking '...\WinSxS\...\wpcip.inf' to '...\DriverStore\FileRepository\wpcip.inf_amd64_868c60ecf2281121\wpcip.inf'. idb: Registered driver package 'wpcip.inf_amd64_868c60ecf2281121' with 'wpcip.inf'. <<< Section end 2026/08/07 12:11:27.810 <<< [Exit status: SUCCESS] # Five differences from the Windows Update case, every one of them decisive: # 1. Section title is 'Stage Driver Updates', not 'Install Windows Update driver'. # 2. cmd: is TiWorker.exe from the versioned WinSxS servicing-stack dir. # 3. INF source is C:\WINDOWS\WinSxS, not SoftwareDistribution\Download\Install. # 4. Signer Score is 0x0D000003 (Inbox), not 0x0D000005 (WHQL). No Submission ID. # 5. Files are Hardlinked, not Copied - and the published name is wpcip.inf, # NOT an oemNNN.inf. In-box packages keep their original INF name. # Also: no Flight Id. Nothing but Windows Update emits a Flight Id.

That is the discriminator, in one table:

Delivery pathSection titleThe cmd: lineINF 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.dllSoftwareDistribution\Download\Install; WHQL (0D000005) plus a Submission ID; a Flight Id is present
Inside a cumulative update / servicing stackStage Driver Updates, Install Driver Updates, Unstage Driver UpdatesTiWorker.exe from the versioned WinSxS servicing-stack directoryC:\Windows\WinSxS\...; Inbox (0D000003); no Submission ID, no Flight Id; files hardlinked
OEM tool, ConfigMgr package, or a script calling pnputil / DISMDriver Install (DrvSetupInstallDriver), Setup Import Driver PackageThe installer's own executable path — read it, it names the culpritWherever the installer unpacked to; signer varies
An application calling the install APIsDevice Install (DiInstallDriver), Device Install (UpdateDriverForPlugAndPlayDevices)The calling applicationApplication-supplied
Plug and play, from packages already stagedDevice Install (Hardware initiated)None. The absence of a cmd: line is itself the signatureDriver 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:

setupapi.dev.log — the Select Drivers block, with real ranks
>>> [Device Install (Hardware initiated) - USB\VID_046D&PID_C548&MI_00\7&1949d121&0&0000] >>> Section start 2026/07/31 09:14:07.356 ump: Install needed due to device having problem code CM_PROB_NOT_CONFIGURED utl: {Select Drivers - USB\VID_046D&PID_C548&MI_00\7&1949d121&0&0000} 09:14:07.417 utl: Driver Node: utl: Status - Selected utl: Driver INF - oem136.inf (...\FileRepository\unifhid.inf_amd64_ba680b8596be64e8\unifhid.inf) utl: Driver Version - 08/24/2021,1.10.80.0 utl: Configuration - USB\VID_046D&PID_C548&MI_00 [LogiLDA.NT] utl: Driver Rank - 00FF0001 utl: Signer Score - WHQL (0D000005) utl: Submission ID - 30033990_14196920964110306_1152921505693844306 utl: Flight IDs - RD:6E439 <-- this driver came from a WU flight utl: Driver Node: utl: Status - Outranked utl: Driver INF - input.inf (...\FileRepository\input.inf_amd64_a22d0c7b993d162a\input.inf) utl: Driver Version - 06/21/2006,10.0.26100.8875 utl: Configuration - USB\Class_03&SubClass_01 [HID_Inst.NT] utl: Driver Rank - 00FF3104 utl: Signer Score - Inbox (0D000003) utl: {Select Drivers - exit(0x00000000} 09:14:07.466 dvi: Searching for hardware ID(s): dvi: usb\vid_046d&pid_c548&rev_0504&mi_00 dvi: usb\vid_046d&pid_c548&mi_00 # Lower rank wins. 00FF0001 (a hardware-ID match) beat 00FF3104 (a # compatible-ID class match). Real rank distribution in this log: # 00FF0001 x90 00FF0000 x57 00FF2001 x17 00FF3000 x16 00FF3001 x15 # Real Status distribution across 237 driver nodes: # Outranked 130 | Selected+Installed 38 | Selected 36 | Outranked+Installed 33 # The 'Flight IDs' field on the SELECTED node is the answer to # "did Windows Update put this driver here?" - for oem136.inf, yes.

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.

Gotcha: if you script this analysis in PowerShell, do not use -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.

  1. Copy the log before anything else. Copy-Item C:\Windows\INF\setupapi.dev.log plus every setupapi.dev.2*.log archive to a share. Everything after this is non-destructive, but a reboot, a rotation or a well-meaning colleague's SoftwareDistribution reset can cost you the evidence.
  2. Identify the package. From Device Manager, or better pnputil /enum-drivers, get the Published Name (oemNNN.inf), Original Name, Provider Name and Driver Version. The published name is your search key for everything below.
  3. 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 the Published '<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.
  4. If the section title is Install Windows Update driver, confirm with the Flight Id and the SoftwareDistribution\Download\Install path, then go to step 7. This is Windows Update, and the question becomes which policy allowed it.
  5. If the section title is Stage Driver Updates or Install Driver Updates, the driver came in a cumulative update via TiWorker.exe. Driver policy is irrelevant. Your lever is the LCU, not ExcludeWUDriversInQualityUpdate.
  6. If the section title names a setup or an API (DrvSetupInstallDriver, Setup Import Driver Package, DiInstallDriver, UpdateDriverForPlugAndPlayDevices), read the cmd: 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.
  7. Read the actual policy state, not the intended policy state. Query HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate for ExcludeWUDriversInQualityUpdate and report present with value or absent, never a bare boolean. Then check ...\DeviceInstall\Restrictions for existence and value count. An absent value means the documented default, and for this policy the documented default is that drivers are allowed.
  8. Only if steps 3 to 6 all came up empty, look at the alternate injection routes: extra paths in DevicePath, and the count of Device Installation Restrictions Policy Check sections, 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.

Read-only policy state — measured, Windows 11 25H2 build 26200.9168
# All read-only. Nothing here changes a single value. === WindowsUpdate policy key === Exists = True TargetReleaseVersion = 1 TargetReleaseVersionInfo = 24H2 ExcludeWUDriversInQualityUpdate present = False <-- drivers are NOT blocked === DeviceInstall Restrictions policy key === Exists = False <-- no device install restrictions === DriverSearching === Policy key exists = False (HKLM\SOFTWARE\Policies\Microsoft\Windows\DriverSearching) Non-policy key exists = True (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DriverSearching) SearchOrderConfig = 1 <-- NOT a policy. Undocumented value name. Report as observed. === DevicePath === DevicePath = C:\WINDOWS\inf Type = ExpandString # Verdict in one line: this device is WUfB-managed, has no driver exclusion, # no device-install restrictions, and the default single INF search path. # Every driver Windows Update chose to offer was allowed to install. The # runbook that says "we block drivers by GPO" is describing a different fleet.

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".

pnputil /enum-drivers — real output and census (ran without elevation)
C:\> pnputil /enum-drivers Microsoft PnP Utility Published Name: oem216.inf Original Name: amdacpbtscoext.inf Provider Name: Advanced Micro Devices, Inc. Class Name: Extension Class GUID: {e2f84ce7-8efa-411c-aa69-97454ca4cb57} Extension ID: {9a11f51a-cff0-444f-b928-0bd7b87c2125} Driver Version: 02/15/2022 2.0.0.453 Signer Name: Microsoft Windows Hardware Compatibility Publisher Attributes: Universal WHCP Version: Unknown # Census from the same run - 2,675 lines of output: Published Name entries : 262 oem*.inf files in C:\Windows\INF: 262 <-- exact 1:1 match, as documented FileRepository folders : 990 <-- the other 728 are in-box packages Class Name Count Provider Name Count Extension 42 Realtek 48 System 47 Advanced Micro Devices, Inc. 30 Camera 45 Lenovo 25 SoftwareComponent 33 Dolby 23 MEDIA 15 AMD 17 AudioProcessingObject 13 Advanced Micro Devices, Inc 10 <-- no full stop Net 11 Fibocom Wireless Inc. 9 Attributes: Legacy 170 | Declarative 47 | Universal 45

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.

FileWhere it actually livesVersion / description on the measured deviceRole in this investigation
wuaucltcore.exeC:\Windows\UUS\AMD64not System321509.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.dllC:\Windows\UUS\AMD641509.2607.1012.0, "Windows Update Deployment Engine"Passed as /DeploymentHandlerFullPath. This is the component that actually drives the driver deployment.
TiWorker.exeThe 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.exeC:\Windows\System32, in every Windows since Vista10.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.dllC:\Windows\System3210.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.dllC:\Windows\System3210.0.26100.1, "Windows Setup API"Writes the text logs you have been reading, via the documented SetupAPI logging functions.
newdev.dllC:\Windows\System326.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.dllC:\Windows\System321509.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 IDMessage (real, captured)What it tells you
20003
Microsoft-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.
219
Microsoft-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.
225
Microsoft-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.
10118
Microsoft-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 IDMessage (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).

Context: be honest about what these catalogues are. Microsoft publishes no event-ID reference for 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 &amp;#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.

Tip: the device installation restriction policies come with a built-in verification step, and it is in the log you are already reading. Microsoft's guidance for every one of these settings is the same: "To verify that the policy is applied, check C:\windows\INF\setupapi.dev.log and see if the following details are listed near the end of the log", followed by a [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:

Removal takes the package out of the driver store so it can never be selected again. The documented tool is pnputil:

Documented pnputil syntax — inspect, export, then remove
# 1. Inventory. Read-only, safe, and where you get the oemNNN.inf name. pnputil /enum-drivers pnputil /enum-drivers /class Display # filter by class (Win11 21H2+) pnputil /enum-drivers /files # list package files (Win11 22H2+) # 2. See which drivers MATCH a device and how they rank. This is the # documented way to check ranking before you change anything. pnputil /enum-devices /instanceid "<device instance ID>" /drivers # 3. TAKE A COPY BEFORE YOU DELETE. This is the step people skip. pnputil /export-driver oem257.inf D:\evidence\ pnputil /export-driver * D:\all-third-party-drivers\ # 4. Remove. /uninstall first updates any devices using the package so they # are no longer installed with it, THEN removes it. /force deletes even # while in use - and is refused for run-from-Driver-Store packages. pnputil /delete-driver oem257.inf /uninstall pnputil /delete-driver oem257.inf /uninstall /reboot # NOT this. /add-driver /install is how the driver got there in the first # place on plenty of "mystery driver" tickets: # pnputil /add-driver mydriver.inf /subdirs /install /reboot # And note the documented caveat: "If the driver is not the highest ranked # driver on the system, PnPUtil will not force it onto the device."

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'".

Watch out: removing the package from the store is not the same as stopping it coming back. If Windows Update offered that driver once, and 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.

Driver provenance audit — measured output, Windows 11 25H2 / 26200.9168
# Everything below is read-only. No service is stopped, no value is written. [1] Inventory Third-party driver packages (pnputil) : 262 oem*.inf in C:\Windows\INF : 262 OK - 1:1, as documented FileRepository folders : 990 (728 in-box) Attributes: Legacy 170 / Declarative 47 / Universal 45 [2] Evidence available setupapi.dev.log : 3,935,513 bytes / 48,837 lines Rotated archives (setupapi.dev.2*.log) : 6 files, 4.27 MB - 5.34 MB Oldest archive : 2025-09-10 ~11 months of history Sections in current log : 273 (546 '>>>' / 546 '<<<', paired) [3] Delivery paths seen in the current log Windows Update (Install Windows Update driver) : 6 Servicing stack (Stage/Install Driver Updates) : 4 Setup / tool (DrvSetupInstallDriver etc.) : 35 API-driven (DiInstallDriver, UpdateDriver) : 2 Plug and play (Hardware initiated) : 4 [4] Policy state that permitted them ExcludeWUDriversInQualityUpdate : ABSENT -> default 0 -> drivers ALLOWED DeviceInstall\Restrictions key : ABSENT -> no ID/class blocks Policies\...\DriverSearching key : ABSENT DevicePath : C:\WINDOWS\inf (default, single path) Restrictions Policy Check sections ran : 109 (evaluation happened; nothing configured) [5] Health signals Error lines '!!!' : 0 Warning lines '! ' : 890 (WDF schema, CR_INVALID_DEVNODE - benign here) Driver nodes: Selected 74 / Outranked 163 Kernel-PnP 219 warnings (30d) : 240 (WUDFRd, baseline noise) VERDICT: driver arrivals on this device are fully explained. Six came from Windows Update, and they were allowed because no exclusion policy exists - not because one was misconfigured. The runbook needs correcting, not the device.

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

Was this post helpful?
React below — no account needed
Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Windows Update
Your Intune update ring says Succeeded: where the policy…
Intune reports delivery of policy, not effective configuration. MDM update settings land…
Windows Update
One read-only PowerShell collector for Windows patching failures…
Test-Path and value checks return confidently wrong patching verdicts on real devices.…
Windows Update
Delivery Optimization says it is peering and your WAN link says…
DO falls back to the CDN silently, with no error and no Event Viewer channel to read.…