Mass Device Driver Installation Using PowerShell and Intune

Let's take a bunch of drivers that we want to install all at once, and deploy them with Intune.

If for some reason you need to be able to deploy a set of drivers to groups of Intune managed devices, then you just found your solution. In this article, I'll be going over how to set up a Win32 app in Intune that will contain and install as many drivers as you wish.

What you will need to follow along:

  1. Microsoft Win32 Content Prep Tool (To package the app to a *.intunewin file)
  2. The driver files that you want to install (these should be *.inf files and any associated files with them)
  3. A Windows virtual machine or spare machine to test your driver installations

Create a folder that contains everything:

This folder will contain everything we want to upload to Intune (our scripts and drivers). For the purposes of this article, I will make a folder called Package at C:\Package.

Now you need to make a folder called drivers, and store it at C:\Package\drivers

You should now have the following two directories:

  • C:\Package
  • C:\Package\drivers

Now create the following four files inside of the C:\Package directory:

  • C:\Package\Install-SpecifiedDrivers.ps1
  • C:\Package\Uninstall-SpecifiedDrivers.ps1
  • C:\Package\install.bat
  • C:\Package\uninstall.bat

Here's an overview of what you should have now:

  • Directories:
    • C:\Package
    • C:\Package\drivers
  • Files:
    • C:\Package\Install-SpecifiedDrivers.ps1
    • C:\Package\Uninstall-SpecifiedDrivers.ps1
    • C:\Package\install.bat
    • C:\Package\uninstall.bat

image

Finally, take any drivers you want to install, and copy them into the \drivers directory. It does not matter if they are nested within folders or not, they will all be installed. In the example I'm using, I have a set of Intel Wireless Bluetooth drivers for Win10/11. There are eight total drivers in the package I'm using, eight *.inf files, all in their own nested sets of folders. Use any drivers you want for this though.

Lets start scripting!

Don't worry, its going to be easy, just copy and paste the code I give you into the associated script files. I'll explain what each script does briefly.

Install-SpecifiedDrivers.ps1
  • Pretty self explanatory, this PowerShell script will loop through every file and folder located within the \drivers directory, and install them using PnPUtil.exe. A registry key is created/set so that we can tell Intune that the drivers are installed. This key will be used as a way to track if drivers are installed through intune. Everything is logged and stored in a text file on the client machine for future reference.
 1# Install any drivers specified in the .\drivers directory using pnputil.exe
 2
 3$TempLogs = "$env:HOMEDRIVE\Temp\Logs\Install-SpecifiedDrivers_LOG.txt"
 4$PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
 5
 6Start-Transcript -Path $TempLogs
 7
 8Get-ChildItem "$PSScriptRoot\drivers\" -Recurse -Filter "*.inf" | 
 9    ForEach-Object { 
10        $DriverFullName = $_.FullName
11        pnputil.exe /add-driver $DriverFullName /install
12        Write-Host "Driver: $DriverFullName"
13    }
14
15# Sets a registry key that Intune can use to decide if a machine already has the drivers installed
16if (Test-Path HKLM:\SOFTWARE\IntuneDriversInstallation) 
17{
18    New-ItemProperty -Path HKLM:\SOFTWARE\IntuneDriversInstallation -Name Installed -PropertyType DWORD -Value 1 -Force
19} 
20else 
21{
22    New-Item -Path HKLM:\SOFTWARE -Name IntuneDriversInstallation -Force
23    New-ItemProperty -Path HKLM:\SOFTWARE\IntuneDriversInstallation -Name Installed -PropertyType DWORD -Value 1 -Force
24}
25
26Stop-Transcript


Uninstall-SpecifiedDrivers.ps1
  • Also pretty self explanatory, this PowerShell script will loop through every file and folder located within the \drivers directory, and uninstall them using PnPUtil.exe. A registry key is created/set so that we can tell Intune that the drivers are uninstalled. Again, everything is logged and stored in a text file for future reference.
 1# Uninstall any drivers specified in the .\drivers directory using pnputil.exe
 2
 3$TempLogs = "$env:HOMEDRIVE\Temp\Logs\Uninstall-SpecifiedDrivers_LOG.txt"
 4$PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
 5
 6Start-Transcript -Path $TempLogs
 7
 8Get-ChildItem "$PSScriptRoot\drivers\" -Recurse -Filter "*.inf" | 
 9    ForEach-Object { 
10        $DriverFullName = $_.FullName
11        pnputil.exe /delete-driver $DriverFullName /uninstall
12        Write-Host "Driver: $DriverFullName"
13    }
14
15# Sets a registry key that Intune can use to decide if a machine already has the drivers installed
16if (Test-Path HKLM:\SOFTWARE\IntuneDriversInstallation) 
17{
18    New-ItemProperty -Path HKLM:\SOFTWARE\IntuneDriversInstallation -Name Installed -PropertyType DWORD -Value 0 -Force
19} 
20else 
21{
22    New-Item -Path HKLM:\SOFTWARE -Name IntuneDriversInstallation -Force
23    New-ItemProperty -Path HKLM:\SOFTWARE\IntuneDriversInstallation -Name Installed -PropertyType DWORD -Value 0 -Force
24}
25
26Stop-Transcript


install.bat
  • install.bat is used as our Install command when we configure the Win32 app in Intune. You could do without this, but it keeps our Install command clean and simple when we configure the app deployment. All it does is launch the Install-SpecifiedDrivers.ps1 script and set the execution policy to bypass so we have no execution issues.
1SET WorkingDir=%cd%
2SET PSPath='%WorkingDir%\Install-SpecifiedDrivers.ps1'
3PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& %PSPath%"


uninstall.bat
  • uninstall.bat serves the nearly the same purpose as install.bat, but we use it as our Uninstall command in Intune. It just sets the execution policy to bypass, and launches Uninstall-SpecifiedDrivers.ps1.
1SET WorkingDir=%cd%
2SET PSPath='%WorkingDir%\Uninstall-SpecifiedDrivers.ps1'
3PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& %PSPath%"

Now to package it up

Using the Win32 Content prep tool, go ahead and package the file. The setup file will be install.bat. Once you run the tool, if all goes well, you should end up with a file called install.intunewin. Once you have this file, you're done on the local end. Now, lets finish configuring everything in the cloud.

Finally, lets create the Win32 app deployment

Head over to Intune:

  1. Select Apps > All apps > Add
  2. In the App type drop-down box, under the Other app types, select Windows app (Win32)
  3. Click Select
  4. Click Select app package file and select your intunewin file
  5. Give your app a Name
  6. Give your app a Description
  7. Give your app a Publisher (this can be anything or anyone)
  8. Click Next
  9. Set Install command to install.bat
  10. Set Uninstall command to uninstall.bat
  11. Set Install behavior to System
  12. Set Device restart behavior accordingly, some drivers require a restart before they start working properly. This is up to you.
  13. Click Next
  14. Set Operating system architecture accordingly, this will depend on your environment. I set mine to 64-bit.
  15. Set Minimum operating system accordingly, this will depend on your environment. I set mine to Windows 10 20H2.
  16. Click Next
  17. Set Rules format to Manually configure detection rules.
  18. Click Add
  19. Set Rule type to Registry
  20. Set Key path to HKLM:\SOFTWARE\IntuneDriversInstallation
  21. Set Value name to Installed
  22. Set Detection method to Integer comparison
  23. Set Operator to Equals
  24. Set Value to 1
  25. Set Associated with a 32-bit app on 64-bit clients to No unless you have reason to otherwise.
  26. Click OK
  27. Click Next
  28. Set dependencies if you think you need them. This might be an app that must be preinstalled before you want the drivers installed for some reason. In this article, there are no dependencies.
  29. Click Next
  30. Set supersedence if you need it for some reason. You shouldn't for this since app since it is just a driver installation.
  31. Click Next
  32. Here you will set any groups of devices you want to make sure get the drivers into the Required section. Any devices you want to uninstall the drivers from, will be put into a group and that group will be assigned to the Uninstall section. Configure this accordingly.
  33. Click Next
  34. Review your settings and make sure you got all the values set properly.
  35. Click Create

And that's it!

Now you just have to wait for your devices to start picking up the new app.

Now there are some limitations to this method...

First, using a single registry key means that you can only use that key for THIS driver package. For example, You have one device model in your tenant (lets call it the Model 0). If you send out a large driver package using this method, you will create a single regkey that could be overwritten at any point. This means that if you want to push out a second driver package to the same Model 0 devices as the first, you MUST change the registry key in the PowerShell scripts. Otherwise, if the key already exists, and is set to 1, then Intune will just assume that the app is already installed, meaning it will not install the second driver package until the registry key is changed.

This registry key business can be entirely bypassed if you are willing to put in the work to find what files are put in place when a certain driver is installed. Then the detection method can be based on if a certain file is present in the system or not. This is obviously preferable, but will take longer with more setup involved. The point of this method is to push out as many drivers as you want in one big package.

And touching on that last point, large files can be a pain to deal with in Intune. You are at the mercy of the end user's internet connection when they begin to download files from Intune. a small 10-20mb driver package is one thing, a larger +100mb package is another. This of course depends on the environment you are in. If all devices are kept within the corporate organization, then perhaps bandwidth isn't that big of an issue, but in a work from home environment, it could potentially pose some issues.