With multiple deployments for task sequences gaining in prominence as a process for In-Place Upgrades, this post will demonstrate a different way to leverage the Modern Driver Management solution in this scenario while not relying on the CCMCache. In the inadvisable event that an In-Place Upgrade is to be used in a Windows 7 to Windows 10 migration, upgrading PowerShell to ensure functionality of Modern Driver Management scripts will also be documented.

The idea behind having multiple deployments to handle In-Place Upgrades (IPUs) is to separate out the preparation functions, such as performing a Compatibility Scan and content pre-staging, from the upgrade process itself. This allows for better error handling, less failures, and shorter upgrade times. For an in-depth look at the process and what can be done with it, check out Gary Blok’s write up.

While Gary’s process is impressive, it’s a little much for the purposes of demonstrating the process of managing drivers and caching with the Modern Driver Management solution. In this write up, two Task Sequences will be used:

As the names imply, “In-Place Upgrade – Compat and Cache” performs the Compatibility Scan and also caches the all of the packages for the next Task Sequence, “In-Place Upgrade – Apply Upgrade”, which does just that.

Modern Driver Management was not originally designed for this type of process, which is demonstrated by the documented parameters we can pass to the Apply Drivers script. What is listed on the documentation is Bare Metal, OSUpgrade, and DriverUpdate. And while all three of these options serve their purposes well, they don’t quite fit the bill for multiple Task Sequences.

In the description section of the Invoke-CMApplyDriverPackage.ps1 (Apply Dynamic Driver) script , there is a PreCache option.

From the description inside the script

There is a separate post entitled “Pre-cache Driver Packages using Modern Driver Management” that discusses how to use the PreCache option natively. That technique takes a different approach than discussed here, but both accomplish the same goal.

To understand why the OSUpgrade and PreCache parameters are not sufficient on their own, it is important to understand how they function.

The “OSUpgrade” parameter downloads the drivers to the “C:\_SMSTaskSequence\DriverPackage\[PackageID]” folder, then it sets the “OSDUpgradeStagedContent” Task Sequence Variable to the path it downloaded the drivers to. This allows the Upgrade Operating System step to know where to look for the new drivers. When the Task Sequence completes, the downloaded drivers are deleted.

The PreCache parameter simply downloads the drivers to the CCMCache folder. It does not set variables of any type. While it is possible to use the CCMCache folder in the second Task Sequence, this may be sub-optimal as the CCMCache could be cleared if there is a delay between running the first and second Task Sequence, or if a need arises to clear the cache.

To solve these limitation, all that is required is a little bit of PowerShell.

The “In-Place Upgrade – Compat and Cache” has the Driver Script configured with the “OSUpgrade” parameter enabled.

Note: -DeploymentType OSUpgrade

This will allow the drivers to be downloaded and evaluated. After the drivers are applied, a Run PowerShell step will need to be added with the following lines:

New-Item -path “c:\” -name Win10DrvCache -ItemType “directory” -ErrorAction Continue

Copy-Item “C:\_SMSTaskSequence\DriverPackage\” -destination C:\Win10DrvCache -Recurse -Force

The contents of the copy script

What these lines do is create a folder named “C:\Win10DrvCache”, continues if the folder exists, and then copies everything that can be found from the original download folder to the new folder. This preserves the drivers in a known location so they can be leveraged during the next Task Sequence.

In the “In-Place Upgrade – Apply Upgrade” Task Sequence, a Set Task Sequence Variable step needs to be added before the Upgrade Operating System step. The variable is “OSDUpgradeStagedContent” with a value of the folder we copied the drivers to.

Setting the OSDUpgradeStagedContent variable

This will allow the Upgrade Operating System step to access the drivers.

At the end of the Upgrade Task Sequence step, an additional PowerShell step should be added to remove the cached drivers:

remove-item -path “C:\Win10DrvCache” -force -ErrorAction Continue

If this process is to be used in a Windows 7 to Windows 10 IPU, there may be some required remediation if the Windows 7 systems did not have PowerShell upgraded during their life-cycle. The installed version of PowerShell in Windows 7 SP1 is 2.0, and this version does not allow the MDM scripts to run.

NOTE – The minimum supported version of PowerShell is version 5.

Upgrading PowerShell in Windows 7 requires a KB to be applied that upgrades the Windows Presentation Foundation (WPF), and can be found here (https://www.microsoft.com/en-us/download/details.aspx?id=54616).

Download the appropriate MSU file, create a package, and provide a program with the following command:

wusa.exe Win7AndW2K8R2-KB3191566-x64.msu /quiet /norestart

While the package can be deployed independently, it can also be integrated into the “In-Place Upgrade – Compat and Cache” Task Sequence. As this package requires a reboot, additional consideration may be required if the Task Sequence is intended to run silently and not disturb the end user. If implementing the PowerShell upgrade into the “In-Place Upgrade – Compat and Cache” Task Sequence, it may be a good idea to incorporate the Modern BIOS Management scripts as the BIOS steps will also require a reboot if a BIOS update is available.

To implement in the PowerShell upgrade into the Task Sequence, some detection and logic will be required to prevent failures if PowerShell has already been upgraded. This can be performed in the following fashion.

Before the steps that run the Modern Driver Management Script, create a Task Sequence Variable called “PSNotInstalled” and set its value to “True”

Creating the variable to handle detection logic

Next, create a second Set Task Sequence Variable step with the same variable name as before, but with the value “False”

The step to determine if the KB is installed

In the Options Tab of this step, create a WMI Query to determine if the KB has been installed. Provide the query with the following criteria:

Select * from Win32_QuickFixEngineering where  HotFixID = “KB3191566”

The WMI query

Next, create a Group with the following Task Sequence Variable condition. This will allow the group to run if the KB isn’t installed:

PSNotInstalled equals “True”

Criteria for the Group to run

In this Group, add the WPF upgrade KB Package and a Restart Computer step.

Once all of this is complete, it should look something like this:

The structure of the PowerShell upgrade function

Now that PowerShell has been upgraded, the Modern Driver Management solution should run as expected!

It’s worth noting that the Task Sequence Engine does not by default log the parameters passed to PowerShell in the SMSTS.LOG file. This is a feature and not a bug. The idea is that credentials or other sensitive information passed to PowerShell will not be recorded in plain text. During the testing of the process, it may be advantageous to enable the logging of parameters. To do this, simply create a Set Task Sequence Variable step, enter “OSDLogPowerShellParameters” as the variable, and the value set to “True”.

Setting the OSDLogPowerShellParameters variable

For reference, this is what the”In-Place Upgrade – Compat and Cache” Task Sequence should look like if every step discussed has been implemented:

The Compatibility Scan and PreCache Task Sequence

Below is what the”In-Place Upgrade – Apply Upgrade” Task Sequence should look like:

The Task Sequence that applies the OS Upgrade

With this process implemented, Modern Driver Management works wonderfully with the multiple Task Sequence IPU method.


  • MrRobot5000
    Posted at 03:49 August 5, 2019

    This stuff right here is GOLD!! Thank you for the good info!!!

  • Marty
    Posted at 10:20 September 3, 2019

    Interesting approach, I’ll try it out. I’m confused by the last two screenshots, why do both Task Sequences have a group named Upgrade The Operating System, shouldn’t that only be in the second one? And why does the Compat and Cache TS have a step named Upgrade Operating System, what is that step doing? Thanks for sharing.

    • Donna Ryan
      Posted at 01:06 September 29, 2019
      Donna Ryan

      The name of the step “Upgrade Operating System” is used twice because it has an option to run the compatibility check against the target machine without upgrading, which is what happens in the first task sequence. In the second, this step does not have the compatibility feature enabled, which allows the OS to be upgraded.

  • Simon Lilly
    Posted at 16:20 November 15, 2019
    Simon Lilly

    Thank you very much. I have read and tried Gary, Mike Terrill and others methods and my conclusion is, this is the way to do it. Cheers

  • Kris
    Posted at 20:40 November 19, 2019

    looks like you may be missing the h in your path for the Remove Cached Drivers Powershell line shown above

    “remove-item -path “C:\Win10DrvCace” -force -ErrorAction Continue”

    • Donna Ryan
      Posted at 03:12 November 20, 2019
      Donna Ryan

      Thanks for finding this. It’s been fixed 🙂

  • MrRobot5000
    Posted at 22:24 December 6, 2019

    I wanted to share what was required for me to do when upgrading Win7 to Win10 after Powershell was updated to WMF 5.1 for modern driver management to work. The issue I encountered was the client halts to function after a portion of the OS upgrade TS.
    More details on this issue and the provided fix is available listed below.


    Best of luck!

    • Donna Ryan
      Posted at 22:33 December 6, 2019
      Donna Ryan

      Thank you so much for sharing the link. I’ll be updating the post with this information.

  • Leave a Reply to MrRobot5000
    Cancel Reply

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