So as we make the move to Modern Management, one of the reoccurring questions I keep hearing is how to automate the deployment of updated drivers to Intune enrolled devices?

This is of course a new situation we find ourselves having to deal with. The traditional model of course is to package driver updates through ConfigMgr and update them on machines using DISM or depend on vendor supplied utilities. So when Microsoft added the ability to run PowerShell scripts through Intune, this got me thinking that I could re-architect parts of our Driver Automation Tool / Modern Driver Management solutions to run locally.

Introducing The Script

Here it is, version 1.0 of the Invoke-MSIntuneDriverUpdate.ps1 which automates the following processes for Dell, HP and Lenovo devices;

  1. Determine the make/model and system sku or baseboard product values
  2. Download or read in an appropriate manufacturer source file and match a driver download
  3. Download and extract the drivers
  4. Install the drivers
  5. Provide full logging for each step of the process

The script in total is 741 lines and just over 30Kb, which is about 1/20th the size of the GUI Driver Automation Tool, so this script is indeed “tiny“.

Prerequisites

The script is for use with Windows 10 only.

Lets Step Through The Process

The first thing to do of course is download the script from the MS Technet Sitehttps://gallery.technet.microsoft.com/scriptcenter/Driver-Automation-Script-a933dd50.

Note: I have also included a copy of the script on our GitHub site in case you wish to expand/branch the script as per your own requirements – https://github.com/SCConfigMgr/Intune/blob/master/Driver%20Automation/Invoke-MSIntuneDriverUpdate.ps1

Now you have the script, lets proceed with rolling it out via Intune:

  1. Log onto your Azure / Intune Portal
  2. Click on Intune on the blades section
  3. Click on Device Configuration

  4. Click on PowerShell Scripts

  5. Click on +Add
  6. Browse and select the Invoke-MSIntuneDriverUpdate.ps1

  7. Click Create
  8. Click on Assignments and assign the script to a group


  9. Monitor the deployment

What To Expect – During Run time

When the script initialises you should see the creation of a Temp folder on the C:\ followed by a series of sub folders. If you are using Dell or HP client devices, the first thing you should see is files starting to appear in the SCConfigMgr\Temp folder. Here you find the downloaded CAB files and extracted XML files used for matching models during the WMI query process in the script. The Lenovo process runs online as the XML is hosted, rather than being contained within a downloadable cabinet file:


You should also see two sub folders, the first of which is the Driver Cab folder and this is used for downloading the compressed driver package files. In the below example you will see drivers from all three vendors:

Dell, HP and Lenovo Driver Files

In the below screenshot you will see the contents of the other sub folder, that being the Driver Files folder. This is where the driver files are extracted to and installed from later in the script:

Example: HP ProOne 600 G2 21.5-inch Non-Touch All-in-One PC – Extracted folder structure

Model Matching

The matching process in the script uses either the SystemSKU or BaseBoard Product values depending on the make of hardware used. For simplicity I have labelled the variable as SystemSKU for all makes, below is an example of the methods used;

# Determine manufacturer name and hardware information
switch -Wildcard ($ComputerManufacturer) {
  "*HP*" {
    $ComputerManufacturer = "Hewlett-Packard"
    $ComputerModel = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty Model
    $SystemSKU = (Get-CIMInstance -ClassName MS_SystemInformation -NameSpace root\WMI).BaseBoardProduct
  }
  "*Hewlett-Packard*" {
    $ComputerManufacturer = "Hewlett-Packard"
    $ComputerModel = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty Model
    $SystemSKU = (Get-CIMInstance -ClassName MS_SystemInformation -NameSpace root\WMI).BaseBoardProduct
  }
  "*Dell*" {
    $ComputerManufacturer = "Dell"
    $ComputerModel = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty Model
    $SystemSKU = (Get-CIMInstance -ClassName MS_SystemInformation -NameSpace root\WMI).SystemSku
  }
  "*Lenovo*" {
    $ComputerManufacturer = "Lenovo"
    $ComputerModel = Get-WmiObject -Class Win32_ComputerSystemProduct | Select-Object -ExpandProperty Version
    $SystemSKU = ((Get-CIMInstance -ClassName MS_SystemInformation -NameSpace root\WMI | Select-Object -ExpandProperty BIOSVersion).SubString(0, 4)).Trim()
  }
}

These values are used as a primary match as they provide a unique identifier for the machine, I have found that the model name doesn’t always provide this exact match. There have been instances however where the SystemSKU value on some Dell machines has not been inserted, so if this occurs the script will fall back to attempting a match based on the model name;

if ($SystemSKU -ne $null) {
      global:Write-CMLogEntry -Value "Info: SystemSKU value is present, attempting match based on SKU - $SystemSKU)" -Severity 1
      
      $ComputerModelURL = $DellDownloadBase + "/" + ($DellModelCabFiles | Where-Object {
          ((($_.SupportedOperatingSystems).OperatingSystem).osCode -like "*$WindowsVersion*") -and ($_.SupportedSystems.Brand.Model.SystemID -eq $SystemSKU)
        }).delta
      $ComputerModelURL = $ComputerModelURL.Replace("\", "/")
      $DriverDownload = $DellDownloadBase + "/" + ($DellModelCabFiles | Where-Object {
          ((($_.SupportedOperatingSystems).OperatingSystem).osCode -like "*$WindowsVersion*") -and ($_.SupportedSystems.Brand.Model.SystemID -eq $SystemSKU)
        }).path
      $DriverCab = (($DellModelCabFiles | Where-Object {
            ((($_.SupportedOperatingSystems).OperatingSystem).osCode -like "*$WindowsVersion*") -and ($_.SupportedSystems.Brand.Model.SystemID -eq $SystemSKU)
          }).path).Split("/") | select -Last 1
    }
    elseif ($SystemSKU -eq $null -or $DriverCab -eq $null) {
      global:Write-CMLogEntry -Value "Info: Falling back to matching based on model name" -Severity 1
      
      $ComputerModelURL = $DellDownloadBase + "/" + ($DellModelCabFiles | Where-Object {
          ((($_.SupportedOperatingSystems).OperatingSystem).osCode -like "*$WindowsVersion*") -and ($_.SupportedSystems.Brand.Model.Name -like "*$ComputerModel*")
        }).delta
      $ComputerModelURL = $ComputerModelURL.Replace("\", "/")
      $DriverDownload = $DellDownloadBase + "/" + ($DellModelCabFiles | Where-Object {
          ((($_.SupportedOperatingSystems).OperatingSystem).osCode -like "*$WindowsVersion*") -and ($_.SupportedSystems.Brand.Model.Name -like "*$ComputerModel")
        }).path
      $DriverCab = (($DellModelCabFiles | Where-Object {
            ((($_.SupportedOperatingSystems).OperatingSystem).osCode -like "*$WindowsVersion*") -and ($_.SupportedSystems.Brand.Model.Name -like "*$ComputerModel")
          }).path).Split("/") | select -Last 1
    }

Driver Update Example

Here you will see an example of a driver updated during the process.

In this example we are looking at the touchpad driver for a Dell Latitude E5470, using the latest SCCM driver package (as of 3/12/2017 – http://en.community.dell.com/techcenter/enterprise-client/w/wiki/11789.latitude-e5470-windows-10-driver-pack):

Dell Driver Pack Note:

Device Manager Post Update:

My demo laptop in this instance was enrolled in Intune and immediately installed the drivers as per the script running, below is an extract from the log:

Review The Logs

Obviously you can monitor the status of the deployed script through the portal, however the script itself also has extensive logging for troubleshooting purposes.

The primary log is the Invoke-MSIntuneDriverUpdate.log located in the C:\Temp\SCConfigMgr\Logs directory (note you can also change the location of the base temp directory in the script). This log will show you all of the key steps undertaken during each step of the script:

The next script is the Install-Drivers.log file, this is generated only once the drivers are available to install using the PNPUtil utility:

 

What Isn’t Covered

At this point BIOS updates and proxies are not catered for. I can add in the BIOS update feature if its something of interest, as for proxy servers I urge you to play around with the script and find out settings that suit your environment.

Other Things To Note

Driver packages are subject to the vendor providing enterprise ready bundled driver packages for use with SCCM. It is these packages which are extracted in the script. If your model is not listed then please refer to the vendor SCCM pages to cross reference against supported models and OS versions.

Dell – http://en.community.dell.com/techcenter/enterprise-client/w/wiki/2065.dell-command-deploy-driver-packs-for-enterprise-client-os-deployment
HP – http://ftp.hp.com/pub/caps-softpaq/cmit/HP_Driverpack_Matrix_x86.html /  http://ftp.hp.com/pub/caps-softpaq/cmit/HP_Driverpack_Matrix_x64.html
Lenovo https://support.lenovo.com/ie/en/solutions/ht074984

Feedback

If you have any feedback, please drop me an email (Maurice@SCConfigMgr.com).

(1179)

Maurice Daly

Maurice has been working in the IT industry since 1999 and was awarded his first MVP Enterprise Mobility award in 2017. Technology focus includes Active Directory, Group Policy, Hyper-V, Windows Deployment (SCCM & MDT) and Office 365.

There are no comments.

Leave a Reply