Inventorying and Reporting on driver information with ConfigMgr

In regards to drivers and BIOS updates on workstations in your environment, a lot of organizations have held the mindset for many years that ‘If it ain’t broke, don’t fix it!‘. We did too up until we had a Windows Desktop RaaS with Microsoft in 2014.

Blog info:

Premier Services site:

What we found is that by not managing our driver and BIOS versions, we had no baseline, and there for a very difficult time troubleshooting hardware and performance related issues. Now we inventory our driver information in SCCM, and can report on how we are doing with versions out in our environment. This information is not available out of the box, so it takes a little setup.

Inventoring the Win32_PnpSignedDriver WMI class

Like all scripts, they should be written in PowerShell, so I created one for a SCCM Script Compliance Item in PowerShell.

A few notes:

  • A new WMI class Win32_PnpSignedDriver_Custom is created. Edit $NewClassName if you would like to change it.
  • The custom class is deleted and recreated on each run
  • The following Properties are inventoried: DeviceClass, DeviceName, DriverDate, DriverProviderName, DriverVersion, HardwareID, DeviceID
  • The timestamp is inventoried
  • Feel free to edit the filter for your own organizations needs
    • $_.DeviceClass -ne ‘VOLUMESNAPSHOT’ -and $_.DeviceClass -ne ‘LEGACYDRIVER’ -and $_.DriverProviderName -ne ‘Microsoft’ -and $_.DriverVersion -notlike “2:5*”

Download the Configuration Item CAB here: Script – Windows – PNP Signed Drivers

Once the script has been deployed and ran on a few machines, just connect to WMI and you can add the new Win32_PnpSignedDriver_Custom class to your SCCM hardware inventory.

Extend hardware inventory – Configuration Manager | Microsoft Docs


Reporting on driver versions

Once you have the data in your inventory, you just need to report on it.

The SQL view v_gs_pnp_signed_driver_custom gets created from your hardware inventory and contains all the raw data. Here are a few sample SQL queries:

Here is a look at some of the raw data:


It was asked by a few members of the community what impact this may have on your database, and how large the table may be. My data is below, but you will need to judge for yourself if this would be an impact to your environment.

There are 77,767 unique resource IDs (total clients reporting) in this table in our environment.

TableName SchemaName RowCounts TotalSpaceKB UsedSpaceKB UnusedSpaceKB
PNP_SIGNED_DRIVER_CUSTOM_DATA dbo 639759 514512 512840 1672
PNP_SIGNED_DRIVER_CUSTOM_DATA dbo 983014 767456 764480 2976

We use the two LAN and WLAN queries above to create a network driver dashboard to report on how standardized we are. We highlight the current standard versions to quickly see any drift.

The .RDL is tailored for our environment, primarily Intel NICs with a few Broadcom and Realtek, so you may need to customize it for your models. The highlights also are “point in time” choices, and will also need to be modified for your needs.

Network – Workstation Dashboard



76 thoughts on “Inventorying and Reporting on driver information with ConfigMgr

  1. I couldn’t resist commenting. Very well written!

  2. Peter Asp

    This is terrific, Ive been working figuring out how to create driver baselines for weeks with no success. I’m having trouble getting the inventory class into SCCM 2012. Can you provide some more details? Thanks

  3. […] default SCCM doesn’t collect drive info. Potent Engineer have a great post about adding driver info to […]

  4. Felix

    Looks clean. What if any impact on HINV if managing 10k endpoints?

    • The only impact is the size of your DB. We inventory over 100 things with HINV, and it runs in about 60 seconds on all of our machines.

  5. Great post Daniel – Many thanks. A couple of queries;
    Do I need to run the script on all client systems? I have only ran it on one by managed to add the custom class to our inventory.
    How long would you expect for it to take for the database to be populated with results? I presume it is dependant on the Hardware Inventory schedule within the default client settings………

    • The scope of clients you want the inventory information on would be who you would target, for both your inventory script as well as client settings to inventory the class. You could target as few or as many as you want. We target all physical workstations for our needs.

      Your hardware inventory cycle schedule does play a part, so it should never take longer than that cycle, plus a little processing time policy to the MP, MP to drop the inventory file, and for the inbox to update and SQL to be injected. We run our HINV daily across all clients so we never expect data to be more than a day or so old.

  6. John Andre Schreuder

    Nice script, WMI class and reports 🙂 Thanks!
    Does the script need to run on a schedule to collect updated information about drivers beeing updated?
    Or is the WMI class dynamic ?

    just looking at the “scriptLastRan” value…


    • Thanks! Yes, the compliance item will need to be re-ran on a schedule to populate new information. We run ours weekly or monthly in some cases.

  7. Your way of explaining the whoe thing in this post is actually nice, all be
    capable of without dificulty know it, Thanks a lot.

  8. Curtis

    Can you give more details on the CI creation? This part has me hung up. I am able to create the class if I run the script manually, but for some reason the CI is not creating the class for the clients. I am able to see that the CI is running, and I can run the CI from the client ad-hoc, but no dice on the WMI class creation. Thoughts?

    • Sorry for the delay! Are you running the script as a monitor, not remediate? Double check your x86/x64 settings as well. We only have x64 clients so we do not check the box to run as x86.

    • I just updated the post with my exact CI export. Give it a try!

  9. Max

    I’m having the same trouble as Curtis. Could you send me a few screenshots of your CI settings?

    • I updated the post with my CI CAB. Give it a try!

      • Max

        It turns out it was an issue with the certificate we used to sign the script. So the CI and baseline are now working when ran manually* but I’m having some trouble with the evaluation schedule. I set a “simple schedule” to run the compliance evaluation every 30 minutes on my test collection but it doesn’t seem to be running at all.

        *Open CM Configurations tab, manually run it by clicking “Evaluate”. The Last Evaluation column updates with the current date and time, the compliance column shows compliant. Open a PowerShell window and run “get-wmiobject win32_pnpsigneddriver_custom | select DeviceName, DriverVersion, ScriptLastRan” the driver version column is updated if a driver was changed and the ScriptLastRan column shows the same info as the Last Evaluation column in the CM Configurations tab.

  10. Anderz

    Hi Daniel, the link gives a 500 – Internal server error…

  11. This is the greatest thing since sliced bread! I love it. Can you share the RDL files of the reports? I would love to use them.

    • Done! They will need to be customized for your needs, but the framework is there!

      • Thx a bunch. The green highlight in the dashboard, is it meant to highlight the newest driver? Or what does it do?

        • For us it represents our current stable driver version. We manually set it, but it could definitely be done dynamically just looking for the max version if you wanted.

  12. Nigel Tatchner

    Hi there, i’m not seeing the view in the SCCM DB any clue why it would still be missing after running for a week and over 1000 clients checking in?

      • Chris Holloway

        I’m having the same issue. It runs on all of the devices as I expect with the configuration item. I connected my hardware inventory to a device and imported the class into the hardware inventory. All boxes are checked. If I loop thorugh my devices they all have this locally. Unfortunately, when I browse to SMS/Site_ with WMI Explorer I do not see the custom table, only the regular Microsoft PNP table. I went ahead and followed your instructions again and removed and re-added it to hardware inventory just in case. I also made sure to cross referenced the above link.

        I’ve checked the inventoryagent.log, no errors but this is what is has to say about the table:

        Any ideas? TL;DR My hardware inventory says it’s being collected but it doesn’t appear to be in the hardware inventroy WMI table.

        • Sounds like the client piece is working correctly. If the clients have the WMI entries locally the CI is working, SCCM just has to tell the client to collect it.

          When you added the class to Default Client Settings, did you enable it? If you have a custom hardware inventory client setting, make sure to enable it there, or whatever client setting is deployed to your clients.

          if that still doesn’t work, remove the class, monitor dataldr.log on your site server, then re-enable the class. There may be an error or other info in the log that may help identify the issue.

          • Chris Holloway

            By “enable” it do you mean check the box for the class?

            Also, I guess I forgot to past the log entry I alluded to above.

          • Yes sir, just checking it in your client settings.

          • Chris Holloway

            or…the html formatting was removing it. Hopefully this one works.

            ![LOG[Collection: Namespace = root\cimv2; Query = SELECT __CLASS, __PATH, __RELPATH, DeviceID, DeviceName, DeviceClass, DriverDate, DriverProviderName, DriverVersion, HardwareID, ScriptLastRan FROM Win32_PnpSignedDriver_Custom; Timeout = 600 secs.]LOG]!><time="11:21:47.727+420" date="09-10-2018" component="InventoryAgent" context="" type="1" thread="10496" file="collectiontask.cpp:478"

          • Chris Holloway

            Ok I did what you suggested. I got no string of errors after doing so. Searching the log, I found this. Googling this is returning BadMIF threads but I’m not having a problem with a single or handful of devices generally. I did look at the device this error was referencing and it didn’t have the table. Overall though, I expect that to be a small subset of devices out of thousands that do have it.

            ERROR – attempt to update non-existent row (sp = pPNP_SIGNED_DRIVER_CUSTOM_DATA). Invalid command: exec dbo.pWorkstationStatus_DATA 1,16787971,’09/11/2018 14:22:41′,1,’9/11/2018 14:21:44′,N’8589934848′,1033,-420 SMS_INVENTORY_DATA_LOADER 9/11/2018 2:22:41 PM 12796 (0x31FC)

          • Chris Holloway

            I had originally misdiagnosed the issue. There is nothing wrong with reporting to the hardware inventory, but I can only seem to get at it using the v_gs_pnp_signed_driver_custom sql method you have outlined above.

            However, I need to build WQL queries for dynamic collections that dig into the SMS\Site_STC namespace. For example, cimv2\WIN32_PNPSIGNEDDRIVER is also stored at sms\site_stc\ as SMS_G_SYSTEM_PNP_DEVICE_DRIVER. From my research this is controlled by SMS_InventoryReport and SMS_InventoryReportClass.

            I’ve found some useful code for achieving this at that will hopefully solve this problem. I’ll post my solution when I get it working.

          • Sounds good. FYI, you should see a new class created in WMI on your PSS called something like sms_g_pnp_signed_driver_custom. You should also be able to query it in a query or collection in the console.

            I’ll check my environment at work tomorrow to see exactly what ours looks like.

          • Chris Holloway

            Were you able to confirm whether you had sms_g_pnp_signed_driver_custom in your sms\site_stc store? I’ve run out of ideas.

          • Hey Chris, sorry for the delay! I checked with WMIExplorer and do see the class on my PSS. The name is SMS_G_System_PNP_SIGNED_DRIVER_CUSTOM. All the data is there. It sounds like you may have an issue with the class being added to the database and WMI. I would monitor dataldr.log, remove it, and re-add it. Maybe see if other custom classes can be added as well.

          • Chris Holloway

            Daniel, Did you have to go into the configuration.mof and add this to the added extensions in order for it to write to the sms/site_stc? Reason I ask is due to the Microsoft note below.

            “If you’ve manually changed the Configuration.mof file to add custom inventory classes, these changes will be overwritten when you update to version 1602. To keep using custom classes after you update, you must add them to the “Added extensions” section of the Configuration.mof file after you update to 1602.”


            We’re running 1706 not sure about you.

          • No sir, anything you add via Client Settings gets added automatically. We only edit configuration.mof for RegKey2Mof changes. Anything straight WMI doesn’t need to be added.

  13. Hari

    Great post Thanks. I copy pasted the script and ran on few machines. The WMI class has been created and in the report also am able to see the driver info of Win 7 machines. However I could not collect info from Win10 physical machines. Is there anything needs to be done for Win 10 environment.

    • Nothing special, it works for both OS for us. Is the class created in the Win 10 machines? Is your CI set to run on both OS? Are the client settings different for Win10?

      • Hari

        Below are the steps which I followed,

        Copy the script to powershell ISE in a win7 machine and ran the script manually. I have not created any CI or compliance baseline.
        After running the script, class got created and added the class to default client settings
        Since I dont want to disturb the default settings, created a custom client settings with only this class and removed it from default client settings
        Deployed the custom client settings to a collection which has all types of machines
        Got the result from win7 machines. However the class did not get created on Win10 machine.
        Am I missing something?

        • In the machine that didn’t report check inventoryagent.log and see if the class was inventoried when hardware inventory was ran.

          • Hari

            In the inventoryagent log the error was Class “Win32 PNP.. custom” does not exist

          • Ah double check the class name and what you have in hinv. Sounds like it may not match exactly.

  14. Hari

    Class name is correct. Instead of typing the full name I gave the short form
    Class Name in the log is “Win32_PNPSignedDriver_Custom” We did not change anything in the PS script.

    • If the class name in WMI and in inventoryagent.log match, not sure what else would prevent it from inventorying. It could be a Windows issue or a SCCM issue, not sure. May want to test on a few other Win10 machines to see if they all fail.

  15. Hari

    To create the class in all the machines for the first time, do we have to deploy the script in each machine once so that the class gets created in all the machines and sends data to the inventory cycle?

    • Yes, you have to create the custom WMI class some way or another. You also have to rerun it to gather new data when there are changes. The script will delete the class and recreate it with the updated data every time it is ran.

  16. GMac

    We are pulling the driver data, but for some reason there is no data being gathered for Universal Serial Bus hardware? Only USB under the System section in Device Manager. Nothing from under Universal Serial Bus section. Anyone have a similar problem?

    • Check WMI locally, is the data there?

      • GMac

        Hi Daniel. Thanks for the reply. Yes it is in WMI. WMI query:

        Select * From Win32_PnPSignedDriver Where DeviceName Like “Intel(R) USB 3.0 eXtensible Host Controller” and driverversion < ""

        Select * From Win32_PnPSignedDriver Where DeviceName Like "Intel(R) USB 3.0 eXtensible Host Controller" and DriverVersion < ""

        • The next thing I would try is to run your Compliance Item script locally and see what output you get. Does it show the USB drivers?

          • GMAC

            Our engineer made an update in the script and it now captures the USB controller data. Thanks.

          • Ben

            It was probably getting excluded from the CUSTOM WMI class because of this line:
            -and $_.DriverProviderName -ne ‘Microsoft’
            I found with this enabled it created A LOT of extra entries because of PnP activity using the Generic Microsoft drivers. Such as Keyboard, Mouse and Monitor unplugging and replugging as well as RDP sessions being active at the time the script was ran etc etc.
            This didn’t have an overly large impact on the “PN_P_SIGNED_DRIVER_CUSTOM_DATA” table, but it certainly did on the “PN_P_SIGNED_DRIVER_CUSTOM_HIST” – depending on how often you run the CI script in the baseline and how often PnP devices were being modified It’s also worth noting that at one stage I configured the HWInventory to collect the “ScriptLastRan” attribute of the Custom WMI class which caused every line to change in the HWInventory every time and this made the “PN_P_SIGNED_DRIVER_CUSTOM_HIST” table MUCH larder. You can see evidence of this in the Historical View of Resource Explorer as well.

  17. Ah great!

  18. Lee

    Some joker has basically done a copy and paste of your article to claim as their own –

  19. Cyprian Wyatt

    Good Stuff… but Just a thought… I changed
    Get-WmiObject win32_pnpsigneddriver -Property DeviceClass, DeviceName,DriverDate,DriverProviderName,DriverVersion,HardwareID,DeviceID |
    where{$_.DeviceClass -ne ‘VOLUMESNAPSHOT’ -and $_.DeviceClass -ne ‘LEGACYDRIVER’ -and $_.DriverProviderName -ne ‘Microsoft’ -and $_.DriverVersion -notlike “2:5*”} …
    $sFilter=”DeviceID != ‘HTREE\\ROOT\\0’ AND DeviceClass != ‘VOLUMESNAPSHOT’ AND DeviceClass != ‘LEGACYDRIVER’ AND Signer != ‘Microsoft Windows'”;
    Get-CimInstance win32_pnpsigneddriver -Filter $sFilter …

    As its been some time since the original post, IMO, $_.DriverProviderName -ne ‘Microsoft’ -and $_.DriverVersion -notlike “2:5*”, are possibly no longer the best filters.

    • I would agree. At the time of the post we didn’t have PowerShell v3 out in the environment, so no CIM cmdlets. Thanks for the suggestion!

  20. Emile Risberg

    This was really helpful, thank you. I have managed to implement this and can retreive data from the view created, I would however, like to you use the collected data to create collections based on driver version etc. such that I can deploy updates in a controlled manner. I do not have much experience creating WQL queries and wonder if anyone has used this for the same purpose successfully?

    • Ah, you do not need to know the WQL, that is just a plus. When you go to create a collection, add a query for the following.

      Attribute class: PNP Signed Driver_Custom
      Attribute: DeviceName, DriverVersion, or DriverDate

      You can filter based on DeviceName and then use DriverVersion or DriverDate to limit what you are looking for.

    • Emile Risberg

      Excellent, thank you for replying so quickly, I´ve tried it now and it works. This has made my week!

  21. Mark

    Hi, about the effect in the database. If my understanding is correct, this would have a great impact if all computers (let’s say 100k computers) have the pnp_signed_driver_custom WMI Class in them, right? If there is no pnp_signed_driver_custom WMI class in the computer, SCCM would not be able to pull data for the driver version and insert it in SCCM’s database.

    Furthermore, if only 1 computer among 100k computers have the pnp_signed_driver_custom WMI class, there will only be entries for 1 computer for the pnp_signed_driver_custom data in the SCCM’s database. Is my visualization correct?

    • Yes, that is correct. For our inventory, we see usually 10-15 entries per machine, so at 100k computers, that would be 1-1.5 million rows. For us, that not is very large. You have to determine what would be acceptable for your environment and database.

  22. Robin Herbert

    Quick observation if I may; the timestamp. Nothing wrong with the $Date variable if your clients are all in one timezone and/or country, but if they’re not then the value and format will not be consistent. It will, by default, be the local client time (without stating UTC offset) and in local client format (e.g., today could be 23/04/2020, 04/23/2020, 23-04-2020, etc.).
    So I changed that line to;
    $Date = (Get-Date).ToUniversalTime().ToString(“yyyyMMddTHHmmssfffffffZ”)
    which will give a consistent time value and format.
    May be useful for anyone publishing scripts to not assume date format.

  23. Nille

    Hi Daniel,

    Nice article.

    Just added the cutom WMI class on our SCCM site server (I found the Win32_PnpSignedDriver_Custom class when searching the class from Hardware Inventory client settings), added all but the view v_gs_pnp_signed_driver_custom is not populated in the CM Database. Also, no info from clients after HW inventory, does the WMI class need to be created on all clients that we need to inventory this custom WMI class ?

    • Hi Nille, that is correct.

      There are two parts, create the class on the clients via script, and then inventory that class with MEMCM. If you run the SQL query for the class on your MEMCM database, and it comes back successfully, but empty, then it was added properly. You just need to run the script on the clients and make sure the custom class is added to your hardware inventory client settings.

  24. Hallo Daniel,
    In my Homelab with VM’s everything is working. Very nice!
    In my production environment I stumble:
    – client-side (Windows-10) everything is working (deployed baseline, WMI class, etc.)
    – Default Client Settings – Hardware Inventory, has the proper class added (imported from a working client)
    – my Database has both Tables and Views, but just no data there.
    Any tips on how to about are appreciated.

    • Rob Bousie

      [ working now ]

      checking InventoryAgent.log, showed lots of:
      [ Inventory: Message [Type=InventoryAction, ActionID={00000000-0000-0000-0000-000000000001}, Report=Delta] already in queue. Message ignored. ]

      [ Invoke-WMIMethod -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule “{00000000-0000-0000-0000-000000000001}” ]

      thanks again for posting this article!

      • Sorry Rob, missed your comment. Glad you got it going!

  25. Dominique Duchemin


    I am confused between the powershell to be run on the clients this will create a WMI class locally but the CAB to be downloaded will do ? Download the Configuration Item CAB here: Script – Windows – PNP Signed Drivers

    • The CAB is to import the baseline into Configuration Manager. You don’t have to create it yourself.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url=""> 

This site uses Akismet to reduce spam. Learn how your comment data is processed.