Precache and update drivers as WIM during In-Place Upgrade Task Sequences with Configuration Manager

Introduction

Not too long ago, I did a post on how to apply drivers compressed with WIM during OSD with Configuration Manager.

Continuing on the same topic and story about ‘Drivers as WIM’, I wanted to explore the option for using WIM when precaching and updating drivers during an In-Place Upgrade of Windows 10. The results made up this new blog post. 🙂

PreCaching Task Sequence

I’m obviously using a separate task sequence for all of my precaching steps. Not all the steps are relevant for this post, so I’m only elaborating on those important for the understanding of this topic.

All of my WIM files are kept in regular packages with no program. One package for each computer model.

For good measures, this is how the content could look like in the Configuration Manager console:

PreCache WIM

First relevant step is to precache the actual WIM file.

In this example, I’m precaching the drivers for Lenovo ThinkPad T470S using a Download Package Content step, into the custom path: C:\ProgramData\KromannReumert\IPUContent\v2004\Drivers

  • The custom path is important to take notice of. Any changes to this path, will require changes later on when mounting the WIM.

I’m also using a WMI filter as a condition, to only download the relevant package for each model.

Post PreCaching

Once the precaching task sequence has run, you will find the content of the package containing the WIM file in the custom path.

In-Place Upgrade Task Sequence

Moving on to using the precached WIM file during the actual In-Place Upgrade Task Sequence.

Mount Drivers Group

I start off by having a group, which is only run if there actually is drivers (a WIM file) precached during the PreCache Task Sequence.

As of such, a condition is created on the group, telling the group to only run the steps, if the path I used in the precaching task sequence exists.

Set SMSTSMountDrivers False

I start the Mount Drivers group off by setting a custom Task Sequence variable SMSTSMountDrivers to False.

I do this, because I need the value of this variable, to determine how some of the following steps needs to be executed.

Mount Drivers

This is the step, where I’m going to mount the precached WIM file. This is probably also the step, which requires the most attention, as this is done with a PowerShell script.

I’ve tried my best with the commenting throughout the script, but what’s essential here is:

  • The name of your WIM file needs to match the computer model/version in order for the script to dynamically find the correct WIM.
  • The paths used here, are used in the precaching task sequence as well as in the in-place upgrade task sequence.
    • If you change the paths, make sure you change it everywhere. 🙂

https://github.com/imabdk/Powershell/blob/master/Mount-DriversWIM.ps1

try {
    # Company Name. This is a part of the paths which are referenced in the precaching task sequence.
    $companyName = "KromannReumert"
    # Windows version. This is a part of the paths which are referenced in the precaching task sequence.
    $waasVersion = "v2004"
    # The content path for this In-Place Upgrade
    $ipuContentPath = "$env:ProgramData\$companyName\IPUContent\$waasVersion"
    # The path where the drivers (WIM file) are precached to by the task sequence
    $driversContentPath = "$env:ProgramData\$companyName\IPUContent\$waasVersion\Drivers"
    # Get the computer version/model. This is used to grab the correct WIM file dynamically. 
    # This requires, that the WIM file is named accordingly
    # The output of this on a Lenovo ThinkPad T480s is 'ThinkPad T480s', why the WIM file is also named 'ThinkPad T480s.wim'
    $computerModel = (Get-CimInstance Win32_ComputerSystemProduct).Version
    if (-NOT[string]::IsNullOrEmpty($computerModel)) {
        $compuderModel = (Get-CimInstance -Class Win32_ComputerSystem).Model  
    }
    # Find the WIM file containing the drivers. This is where the computer model needs to match the precached WIM file
    $findDrivers = (Get-ChildItem -Path $driversContentPath -Recurse | Where-Object {$_.FullName -match $computerModel}).FullName
    # Mount drivers if a matching WIM file was found
    if (-NOT[string]::IsNullOrEmpty($findDrivers)) {
        if (-NOT(Test-Path -Path $ipuContentPath\MountDrivers)) { New-Item -Path $ipuContentPath -Name MountDrivers -ItemType Directory }
        dism.exe /mount-wim /wimfile:$findDrivers /index:1 /mountdir:$ipuContentPath\MountDrivers
    }
}
catch {
    Write-Verbose -Verbose -Message "Failed to mount WIM containing drivers"
    exit 1
}

Set SMSTSMountDrivers True

Now I want to change the value of the SMSTSMountDrivers variable to True, but I only want to do that if the WIM indeed was mounted.

Therefore this is done with a condition, to only run the step, if the previous step was successful.

Set OSDUpgradeStagedContent

Here I’m leveraging a task sequence variable called OSDUpgradeStagedContent, which essentially instructs the Windows setup to use the content that I now have mounted via the WIM file.

And again, to prevent unexpected errors and failures, this is only done if the mount of the WIM file was successful.

Unmount Drivers

Finally and post upgrade, I’m unmounting the WIM again. This will automatically clean up the mounted files.

This is done with a condition as well, so the task sequence only tries to unmount the WIM, if it was mounted in the first place.

  • dism.exe /unmount-wim /mountdir:C:\ProgramData\KromannReumert\IPUContent\v2004\MountDrivers /discard

Cleanup Precached Drivers

As a good practice, I don’t want to leave behind a bulky WIM file taking up space, so once the In-Place Upgrade is successful, I delete the directory where the WIM was precached to.

And I only do so, if there is something to delete.

ENJOY 🙂

Leave a Comment

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