So you have deployed your machines with the latest and greatest drivers and BIOS updates. But then the questions of what to do to maintain your systems post deployment?, or do I upgrade the BIOS and drivers as part of an upgrade TS?

These are questions that I have had asked more than a few times of late. In answer to your question, there are several methods to maintain both the BIOS and drivers on the machines but most are vendor specific / developed.

The vendor utilities where available do a good job, the Dell Command Update utility is an excellent example of how to do things right. In some cases however, this means also maintaining a separate master repository for the machines to scan or allowing internet access. When you talk about allowing machines to maintain their driver and BIOS version over the internet, the lack of version control is something that most ConfigMgr admins will complain about. The complaints are justified though, as we all know that system stability can be greatly affected by drivers. So this got me thinking.

Maintaining the BIOS version through our Modern BIOS Management approach has been around for a little while now, so I thought I would extend this maintenance approach to cater for drivers. Below I will show you how you can wrap this up into a single task sequence and then deploy this to your client fleet. You can of course have it re-run as often as you wish within a maintenance window or on-demand for those mobile workers who are seldom in the office.

PowerShell + WebService FTW

Most of you who are familiar with our MDM & MBM solutions will know that we can dynamically determine/download the latest available versions of driver and BIOS packages from ConfigMgr. So I have extended the Invoke-CMApplyDriverPackage.ps1 script used to undertake driver matching and downloading in WinPE with an additional switch, that being the “OSMaintenance” switch. The new switch allows you to tell the script to perform some actions differently, the key action of course being to avoid the DISM step which we cannot undertake on an already deployed OS.

When run with a $true value for the optional OSMaintenance switch works to detect the currently installed version of Windows, this time however not based on the WIM being deployed but on the properties of the NTDLL.DLL. If a matching package is found, it is downloaded and then ready for the next step. Note: This does mean that your task sequence will require a reboot into WinPE for this process to complete, this is due to the method in which we leverage the OSDDownloadContent command.

Applying Drivers

Having taken influence from an earlier post by Mikael Nystrom (https://deploymentbunny.com/2011/05/07/adding-drivers-using-pnputil-and-forfiles/), I have created an additional PowerShell script that leverages the fact we already have a process for downloading the latest available driver package from ConfigMgr. Using the PNPUtil command all we need to do is point the utility at the location to which we downloaded the driver package and your system will then detect and install the latest drivers contained within;

# Apply driver maintenance package
try {
	Write-CMLogEntry -Value "Starting driver installation process" -Severity 1
	Write-CMLogEntry -Value "Reading drivers from $DriverPackagePath" -Severity 1
	if ((Get-ChildItem -Path $DriverPackagePath -Filter *.inf -Recurse).count -gt 0) {
		Get-ChildItem -Path $DriverPackagePath -Filter *.inf -Recurse | ForEach-Object {
			pnputil /add-driver $_.FullName /install
		} | Out-File -FilePath (Join-Path -Path $LogFilePath -ChildPath DriverMaintenance.log) -Force
		Write-CMLogEntry -Value "Driver installation complete. Restart required" -Severity 1
	}
	else {
		Write-CMLogEntry -Value "No driver inf files found in $DriverPackagePath." -Severity 3; exit 1
	}
} catch [System.Exception] {
	Write-CMLogEntry -Value "An error occurred while attempting to apply the driver maintenance package. Error message: $($_.Exception.Message)" -Severity 3; exit 1
}

 

The Task Sequence

In the sequence below there are 8 key steps with others being optional. This will ensure that your machine is kept up to date at all times. Remember this requires no client software and you can tailor logging values to suit your environment.

 

Lets step through the process
  1. Suspend your disk encryption protection to allow for the BIOS to be updated
  2. Restart the computer into WinPE
  3. Run the Invoke-CMDownloadBiosPackage.ps1 PowerShell script.
  4. Run the vendor specific BIOS update script, in this example we are using the Invoke-DellBIOSUpdate.ps1 for Dell system. Restart to apply BIOS. (You can create a group for the BIOS update process and apply a WMI filter using a variable check for NewBIOSAvailable equals “True”. This will prevent the system attempting to flash the BIOS and restart if the version if current)
  5. Run the Invoke-CMApplyDriverPackage.ps1 PowerShell script with the following switches:
    -URI “http://%YOURSERVERNAME%/ConfigMgrWebService/ConfigMgr.asmx” -SecretKey “%YOURSECRETKEY” -Filter “Drivers” -OSMaintenance
  6. Restart the computer into the full OS
  7. Run the Invoke-CMDriverMaintenance.ps1 script to apply drivers
  8. Restart the computer to commit the driver updates

Example

In the below example we have a Dell Optiplex 7040. Looking at Dell’s SCCM driver site, we can determine that we should be expecting at least the following drivers to be updated as part of the maintenance TS.

Arch Category Device Description Previous CAB Current CAB Status
x64 audio Realtek High-Definition Audio Driver ReleaseID: DDG39
DellVersion: A06
VendorVersion:6.0.1.6111
ReleaseID: RT1XX
DellVersion: A07
VendorVersion:6.0.1.6117
Updated
x64 storage Intel Rapid Storage Technology Driver and Management Console ReleaseID: 02RN8
DellVersion: A05
VendorVersion:15.2.10.1044
ReleaseID: CRRKJ
DellVersion: A07
VendorVersion:15.2.15.1058
Updated
x64 video Intel HD, 500, P500 series Graphics Driver ReleaseID: WNF3C
DellVersion: A10
VendorVersion:21.20.16.4590
ReleaseID: TDP4X
DellVersion: A11
VendorVersion:21.20.16.4627
Updated

Driver Package A09 – Source: http://en.community.dell.com/techcenter/enterprise-client/w/wiki/11660.optiplex-7040-windows-10-driver-pack

Intel Storage Driver

 

PowerShell Script Sources

The PowerShell scripts referenced are available on GitHub – https://github.com/SCConfigMgr/ConfigMgr/tree/master/Operating%20System%20Deployment. Here you will also find an optional script for applying a maintenance notice and background (as pictured in the task sequence) – https://github.com/SCConfigMgr/ConfigMgr/blob/master/Operating%20System%20Deployment/Invoke-ITMaintenanceMessage.ps1

Conclusion

Maintaining drivers and BIOS versions can easily be automated with this method. Now set up your task sequences, deploy and keep your environment current.

 

(4483)

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.

comments
  • John
    Posted at 03:16 October 18, 2017
    John
    Reply
    Author

    Are the driver packages referenced traditional ConfigMgr driver packages or standard packages used for drivers?

    As always, thank you for your contributions to the community.

  • Jeremy Kowalski
    Posted at 21:26 October 18, 2017
    Jeremy Kowalski
    Reply
    Author

    First, a request. It was really nice back when the Invoke-CMDownloadDriverPackage.ps1 didn’t actually download the driver because then you could use it as an approved/included model detection. It would be great to have a script or parameter to replicate this functionality, either on the legacy Invoke-CMDownloadDriverPackage or the updated version, Invoke-CMApplyDriverPackage. For now, we’re sticking with the NickolajA v1.0.8 for its speed while keeping a task sequence prepped with the SCConfigMgr version for its eventual beneficial deployment.

    Second, some notes regarding shifts and changes between the NickolajA and SCConfigMgr scripts.
    1) The scripts moved from using the model name in the package title to the SKU in the description for its detection. If you have to add new drivers manually, set both the title as well as the description for your packages or they will fail to detect and apply.
    2) If using Windows Servicing\Invoke-CMDownloadDriverPackage v1.1.4: Remove the “Download Driver Package” task, and the “Apply Drivers via DISM” needs to be /Driver:%OSDDriverPackage01% not /Driver:%DriverPackage01%\ as in the step-by-step directions. If you leave the download task in, it will actually download whatever package is defined instead of your drivers. Also as noted above, remove the trailing \ as it’s now included in the variable and will fail when it tried to parse it again. Tested and this worked fine with those changes.
    3) Using the new Drivers\Invoke-CMApplyDriverPackage v1.1.5: Remove both the download and application tasks. It’s all self-contained now.

    Third, thanks. 🙂 Looking forward to when we get to see this working in production.

  • ben
    Posted at 12:15 October 20, 2017
    ben
    Reply
    Author

    Hi Maurice,

    i’m missing two things?
    1. Download BIOS Package
    2. Resume Bitlocker.

    Could i use “Enable Bitlocker” TS Step after the last reboot? or should i use Manage-Bde -Protectors -Enable C:?

    Regards
    ben

    • Maurice Daly
      Posted at 14:54 October 20, 2017
      Maurice Daly
      Reply
      Author

      Hi Ben,

      The download BIOS package is contained within the Invoke-CMDownloadBIOSPackage.ps1 script. In regards to Bitlocker, encryption will automatically resume post full OS restart.

      Maurice

  • Chris
    Posted at 20:09 October 20, 2017
    Chris
    Reply
    Author

    Hello Maurice,

    Your scripts are awesome and I am trying to get it working in my Lenovo environment. I noticed in my task sequence I am getting “PowerShell.exe does not exist at ‘X:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe’ when trying to run the Invoke-CMDownloadBIOSPackage.ps1 script.

    I am trying to replicate your task sequence by running the bios download and install steps right after the Apply Operating System step. I assume this is still in Windows PE? Any idea what my issue is here? I am a bit of a SCCM noob but your scripts and tools are making the upgrade to windows 10 for my fleet a great help! Thank you

    • Ben
      Posted at 08:36 October 21, 2017
      Ben
      Reply
      Author

      Hey Chris,
      I think you are missing Powershell Features in WinPE
      You need to add that to your boot image. Right click on the boot image you use in that TS properties select Powershell Modules and Update Image to Dps.

      • Chris
        Posted at 17:59 October 25, 2017
        Chris
        Reply
        Author

        Thanks for the reply, that sure was it! Now interestingly its able to find the bios in my package list, but I am getting a “You cannot call a method on a null-valued expression error” in my smsts log when running the download package command. Is it possible the %OSDBIOSPackage% variable is incorrect, or do i need to declare it before in my task sequence? I have seen it referenced a few different ways in the scripts here. Or is it possibly some other issue?

        • Maurice Daly
          Posted at 23:07 October 25, 2017
          Maurice Daly
          Reply
          Author

          Hi Chris,

          The variable should be set to %OSDBIOSPackage01% when calling it in the vendor script.

          Maurice

    • Mario
      Posted at 12:18 October 21, 2017
      Mario
      Reply
      Author

      Hi Chris – you’ll need to make sure you have the powershell components added to your boot wim that you’ve assigned to the task sequence.

  • Thomas
    Posted at 10:09 October 25, 2017
    Thomas
    Reply
    Author

    How about a Powershell script that in the same matter that can compare and verify PC_BIOS hardware class, against specific model bios packages available, so one can find which models need to update their bios?

    all this info are in sccm, so it should be doable?

  • Skylar
    Posted at 19:12 November 15, 2017
    Skylar
    Reply
    Author

    So I added this to my In-place Upgrade TS for Windows 10, however it always fails when running the Invoke-CMApplyDriverPackage step. The error is:
    Get-Item : Cannot find drive. A drive with the name ‘C’ does not exist.
    At D:\_SMSTaskSequence\Packages\*packageNameRemoved*\Operating System Deployment\Drivers\Invoke-CMApplyDriverPackage.ps1:374 char:23

    I’ve made sure after upgrading the OS to reboot into WinPE. I’m also confused about why this caused the whole TS to fail as I have “Continue on Failure” checked for that step, but maybe I should apply that to the whole group instead of the individual step.

    So, what can I do about it not being able to find the C: drive? Or can I just not include this in this particular TS? Or because I am laying down a new OS, should I not be using the -OSMaintenance switch?

    Any insight would be appreciated!

  • Suresh
    Posted at 16:45 November 20, 2017
    Suresh
    Reply
    Author

    Hi, I was using dynamic driver update Invoke-CMDownloadDriverPackage.ps1 for staging the driver package for my in-place upgrade from windows 7 to windows 10 1709 and am using “Upgrade Operating System Enterprise” option for the upgrade. Every time it is failing on “GetCMOSImageVersionForTaskSequence” action and it errors out “An error occured while calling ConfigMgr WebService to determine OS Image version. Error message”. Is there a limitation for 1709 OS since it has multiple index.?

  • Jonathan
    Posted at 10:58 November 22, 2017
    Jonathan
    Reply
    Author

    Hello,

    Thank you for your excellent tutorial. However, the system doesn’t seem to install the drivers.

    Invoke-CMDriverMaintenance.ps1 points to a script called Invoke-ITMaintenanceMessage

    https://github.com/SCConfigMgr/ConfigMgr/blob/master/Operating%20System%20Deployment/Drivers/Invoke-CMDriverMaintenance.ps1

    Is this the same version? I don’t see any action to install the drivers in the script specified.

    Thank you in advance!

    Jonathan

    • Maurice Daly
      Posted at 11:35 November 22, 2017
      Maurice Daly
      Reply
      Author

      Hi Jonathan,

      It looks like the contents of that script was mixed up with another. I have just replaced it on GitHub.

      Maurice

  • Keith Morris
    Posted at 20:13 December 7, 2017
    Keith Morris
    Reply
    Author

    I’m in the process of trying to update the BIOS using ConfigMgr WebServices with the Invoke-CMDownloadBIOSPackage.ps1 and the Invoke-LenovoBIOSUpdate.ps1 scripts. I followed the steps in your directions but I keep getting the following error in the smsts.log file. The BIOSPackageDownload.log file is never created.

    Executing command line: Run Powershell script RunPowerShellScript 12/7/2017 1:56:09 PM 1500 (0x05DC)
    C:\_SMSTaskSequence\Packages\GCS0012D\Invoke-CMDownloadBIOSPackage.ps1 : A positional parameter cannot be found that RunPowerShellScript 12/7/2017 1:56:13 PM 1500 (0x05DC)
    accepts argument ‘Update’. RunPowerShellScript 12/7/2017 1:56:13 PM 1500 (0x05DC)
    At line:1 char:1 RunPowerShellScript 12/7/2017 1:56:13 PM 1500 (0x05DC)
    + & ‘C:\_SMSTaskSequence\Packages\GCS0012D\Invoke-CMDownloadBIOSPackage … RunPowerShellScript 12/7/2017 1:56:13 PM 1500 (0x05DC)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RunPowerShellScript 12/7/2017 1:56:13 PM 1500 (0x05DC)
    + CategoryInfo : InvalidArgument: (:) [Invoke-CMDownloadBIOSPackage.ps1], ParameterBindingException RunPowerShellScript 12/7/2017 1:56:13 PM 1500 (0x05DC)
    + FullyQualifiedErrorId : PositionalParameterNotFound,Invoke-CMDownloadBIOSPackage.ps1 RunPowerShellScript 12/7/2017 1:56:13 PM 1500 (0x05DC)

    Any help would be appreciated.

    • Nickolaj Andersen
      Posted at 10:46 December 10, 2017
      Nickolaj Andersen
      Reply
      Author

      Hi Keith,

      Could you please share a screen shot together with the command line options set for the Run PowerShell Script step?

      Regards,
      Nickolaj

      • Keith Morris
        Posted at 21:23 December 11, 2017
        Keith Morris
        Reply
        Author
        • Keith Morris
          Posted at 21:25 December 11, 2017
          Keith Morris
          Reply
          Author

          Also, the Modern BIOS Management is a package that contains the Invoke-CMDownloadBIOSPackagd.ps1 and the Invoke-LenovoBIOSUpdate.ps1 PowerShell scripts.

          • Maurice Daly
            Posted at 23:55 December 11, 2017
            Maurice Daly
            Author

            Hi Keith,

            What version of the Invoke-CMDownloadBIOSPackage script are you running?. The current version is 1.0.6.

            Maurice

    • Jeremy Kowalski
      Posted at 16:17 December 11, 2017
      Jeremy Kowalski
      Reply
      Author

      Also make sure that your filter is “BIOS” not “BIOS Update”, as listed in line 17.

      • Maurice Daly
        Posted at 16:42 December 11, 2017
        Maurice Daly
        Reply
        Author

        Hi Jeremy,

        You can use either in fact. As long as the packages were created by the driver automation tool, their naming structure will be “BIOS Update – %MAKE% %MODEL%”, so using BIOS or BIOS Update as the starting wildcard / matching value is fine.

        Maurice

        • Jeremy Kowalski
          Posted at 18:53 December 11, 2017
          Jeremy Kowalski
          Reply
          Author

          Interesting, as I received the same error as Keith when I tried to do the multiple word filter (BIOS Update) and it was solved by following the directions with the single word.

          It’s possible that the script has been updated to work with pilot updates and in doing so, it’s able to function with the multi-word filter and that Keith is on the same (or a similar) older version without that functionality.

          But I had experienced Keith’s same issue and did not report it as following directions strictly fixed it, making it a failure to read rather than a failure in the code. Our organization has not tried to deploy pilot updates, so I don’t know whether that would have worked or had the same issue.

  • Leave a Reply