WaaS–Post 1–PreCache Compat Scan TS

So this will be the first of several posts, well, it’s sorta the second, this heavily relies on the Script I posted for writing values to registry & WMI a few posts ago, however I’ve made several modifications to it since then, and have done A LOT of testing. Hence my last post about testing Low Disk Space machines.

WaaS Process, as Designed by Mike Terrill & Keith Garner quick overview:

  1. PreAssessment:  Set of Rules run against hardware inventory data to rule out machines that be known to fail the upgrade. Rules include:
    1. Hardware Checks
      1. Models
      2. Free Disk Space
      3. Memory
    2. Software Checks (Software we know that needs to be at specific versions to survive IPU, or not block it)
      1. 3rd Party Encryption Version level
      2. 3rd Party AV Version level
      3. Several other Apps
    3. General Checks
      1. Last HWInv Date
      2. Last MP Checkin
      3. OS / Build / OS Arch
      4. CCM Cache Size
  2. PreCache / Compat Scan (Task Sequence): After it passes all of the rules, the computer then added to a collection targeted with this TS.  The TS is setup as a Required Deployment, and set to Pre-Download Content, and Download all Content before starting the TS.  Then will dynamically download the driver packages, run the Check Readiness, and then Compat Scan.
  3. Schedule for Upgrade: After it has been cached, and passes the compat scan, the machines can be schedule (added to collection targed with the upgrade).

That’s a really quick overview of how we’ve setup WaaS, we went over this in great detail @ MMS, and I’d expect Mike Terrill to eventually blog that detail, I just don’t want to steal all of this thunder, but felt you needed a little overview to explain where this TS fits in.

This post will be covering PreCaching your Upgrade Media and Drivers, along with running the Compatibility Scan.

Here is what the TS looks like:

So Lets break this down:

  • Set SMSTSPersistContent & Set SMSTSPreserveContent (note the misspelling in the TS image, my bad) – Set both to true so that when you download the packages for the TS, it saves it to the CCMCache so it doesn’t remove after the TS Completes.
  • Set OSD Info Type & Set OS Build Version.  Variables used in scripts and steps later on.
  • Set WaaS_Stage (Sets registry Key, Eventually I want to go back and make this write to WMI as well, just haven’t had time)
  • Set TS Var – Sets SMSTS_StartTSTime to the current time, to be used to calculate how long the TS ran.
  • Power Settings Change – Details HERE
    • Set TS Var “PowerPlan” to Active Power Plan – This is grabbing the current power plan running and places that info into a variable
    • Set Power Options – High Performance – Sets the machine to High Performance power plan, to hopefully speed up the process
  • Set Driver and Content Download (Group)
    • Set Dynamic Variables (Model & Package)  This is a simple way to map Models to Packages of Drivers.
    • Download Drivers and Content (Group)
      • Set Download Start Time
      • Set SMSTSDownloadProgram to Null
      • Set Driver Download Variables
      • Download Driver Package
      • Reset Download Variables
      • Set Download Finish Time
  • Storage Cleanup (Group) Runs if Free Space < 20GB Free – Not going to go into in this post
  • Check Readiness (RAM & Free Space)
    • Set CheckReadiness Pass (sets variable to “Pass”) by default, if an upcoming step fails, it updates
    • Check Readiness – Memory
    • Set CheckReadiness PHail Memory (If last step fails, it sets CheckReadiness to “Memory”
      image image
    • Check Readiness – Free Space
    • Set CheckReadiness PHail Free Space (if last step fails, it sets CheckReadiness to “FreeSpace”
      image image
  • Compatibility  Scan Section (Group) – Runs if CheckReadiness = Pass

    • Add Key to remove from Provisioning Mode – Creates run once key with command to remove from provisioning mode (safe guard)
    • Set Start Upgrade Time
    • OS Compat Scan – Upgrade Step set to Compat Scan Only
    • Set Finish Upgrade Time
    • Delete Key to remove from Provisioning mode
  • Power Settings Restore
    • Set Power Options – Balanced (Runs if PowerPlan = Balanced)
    • Set Power Options – Power saver (Runs if PowerPlan = Power saver)
  • Set TS Finish Time
  • Tweak – SetOSDInfo PS – Runs the script that writes all of the metrics to WMI & Registry
  • Send Hardware Inventory
  • Copy Logs to Server (if CompatScan was not successful)
  • PHail Section
    • Set TS Var ReturnErrorCode” – Setup No Run – The will set the Variable ReturnErrorCode to 20 (arbitrary number that is not 0) if compatscan never ran
      image image
    • Set TS Var “ReturnErrorCode” – Setup Ran – This will set the ReturnErrorCode to the Return Code of the CompatScan
    • PHail if CompatScan PHailed


And there you have it, the PreCache Compat Scan TS

TS Properties: Advanced Tab: Check Box for “Suppress Task Sequence notifications”

Sorry, all of the steps are just images, but the actual TS is available for download HERE


General: Defaults.  You might be asking, why not use the “Pre-Download Content…” option, well, that only comes into play if the deployment is “Available” vs “Required”.  Since it is a required Deployment, it will start to download right away anyway.  If you’re making the TS “Available” to a group for testing, it would probably be worth checking that box.

Scheduling:  We have it set to run each day @ 8PM.  Once it runs successfully we have it automatically move to the next collection, if it fails, it will just try again the next night, hopefully you’ve remediated anything that prevented it from running properly.  Change the schedule to fit your environment.  In my lab, this works fine, as I have collection queries move it out once it is successful. That’s another blog post down the road.

User Experience… HIDDEN… we don’t want the users to even know this is going on.

Distribution Points: Download all content locally before starting the task sequence.  Question: How long do we want the TS to run??  Answer: As short as possible.  Pre-Download all content also ensures that we have all of the content needed before starting.  If it can’t get the content it doesn’t start.  Less chance of failure during the actual TS.  Consider this, you have a remote user with little bandwidth, it will take hours for the content to download, if you didn’t have it download the content ahead of time, that TS would run for hours, with a high change of the user rebooting, or turning off the machine in the middle of the TS.  Anyway, I think you get the point, download the content prior to starting the TS.


Example of Results (Fail Low Free Disk Space)

Example of Results (SUCCESS!)

Note, if you look at these metrics, you’ll be like… wait a minute, how was your Task Sequence run time less than the time it took to download the drivers.  Well, it downloaded the Drivers in Run 1, which then failed the Free Space Rule.  During Run 2, it had already downloaded the drivers, so it didn’t need to waste those 4 minutes again, and so the entire 2nd run only took 3 minutes.  The Script to capture this info, writes the time it took to download drivers, the 2nd time you run it, it checks that key, if it’s greater than 0, it will leave it alone, and keep the current value from the last run.


The Content needed for my IPU is now in my CCM Cache, which will make the IPU start instantly, no need to wait for the download. (Upgrade, Drivers & Scripts Packages)

If you need any clarifications on this post, please let me know and I’ll try to update it.  When you work on these things every day, it’s easy to miss explaining something.

Originally Posted on GARYTOWN.COM – 2018.06.05

63 thoughts on “WaaS–Post 1–PreCache Compat Scan TS”

  1. Excellent post!
    The WaaS sessions were my favorites at MMS. I really appreciate you taking the time to write these articles explaining the details of how it’s done.
    Thank you.

  2. I am starting to deploy IPU, and wanted to check the clients before deploying….So i will need some time to create a TS and test it.
    Can you please post links if you have for “Copy Logs to Server” i think i have seen it in your blog. And also currions what are the queries to move from collection to a collection.
    Do you use any reports to review the “Check Readiness TS” from the night before?
    Thank you.

  3. Looking at your TS i am still missing where are you passing a parameter to a “Copy-LogsToArchive.ps1” i dont see it in the script and nothing in the TS: -LogID “IPU\%SMSTS_Build%\%ComputerName%”

    • Looking at the script and the parameter defaults I think it’s just crossed wires.

      The %SMSTS_Build% in the Parameters field looks like it would match up with the variable %osbuildversion% being set at the start of the sequence.

      The %ComputerName% variable is simply the computer’s name. So that can be assigned any number of ways ($env:ComputerName for example). Or you could use one of the native SCCM TS variables for the computer name.

  4. Very helpful! cannot understand why I don’t have this option as built in.

    Question? If you have bad Drivers etc as application is there a way to treat them the same way?


    • Hey Robert, If it’s a hardblocker, they will all get caught during the Compatibility Scan, doesn’t matter if Driver or App, if MS thinks it’s a blocker, it will let you know.

  5. Gary, this is rock solid! I’m learning a great deal going through this. I keep finding myself saying, “Why didn’t I think of that?”

    Great work!

  6. Hi,
    Thank you for this good post, it helps manage the upgrade process in a more streamlined manner for us.
    Just a small question, for the Dynamic variable for driver package you use
    OSDDownloadDestinationVariable to DRIVERS but when I see where the drivers are downloaded its with a folder name with random letter ex: a / f / e..
    I was hoping to download the drivers to c:\windows\CCMcache\Drivers location so I can use this location during my IPU TS.

    Is it possible to make this change in your TS? or any where in the script if so could you let me know . thanks!

    • Basically, you run the exact same group in your actual upgrade TS, so it will try to download again, (but sees it already has the content and doesn’t need to download again), then creates that variable DRIVERS again, which you’d use. I’ll cover that in my next post… as soon as I get time to post it.

  7. Hi Gary. I have been testing the pre cache as part of our move to win 10. We are cacheing all the content but how do you get the os upgrade to use the cached copy to upgrade. Everything I have tried downloads the os package again adding 20mins to the upgrade.

    Thanks for the great blog

    • If you set the 2 TS variables at the start of your PreCache TS, it will remain on the client cache. SMSTSPersistContent & Set SMSTSPerserveContent. Then when you upgrade TS runs, as long as the content hasn’t changed from the time you precached to the time you run the upgrade, it will use the upgrade content you already downloaded.

  8. Hi Gary, how are you reconciling updating/servicing the WIM and having it pre-cached on a bunch of machines? I ran my compatScan a week ago, and now I have a new WIM!?!

    do you only update and do an IPU within a small time window?

    • We try to schedule a machine pretty quick after it is cached. However, if it does fall during the the period where we updated the WIM, because the deployment is set to required, it will start to cache again in the background once it receives the updated policy. Thank you for the question, I’ll try to update the post soon to cover that.

  9. Hey Gary,

    Hope all is well, thanks for the excellent write up, trying to implement now. You talk about moving your devices from one collection to the next, I know you discussed this during the MMS walk on WaaS but was wondering if you or any of your cohorts have a write-up how this actually works. I’m trying to get my head around the whole process and this is obvious the first step in the larger picture.

    Also curious about the hidden task sequence as when I created the deployment and my lab machine checked policy I got notification of a change in software center and when I pulled up SC there was a new item under Operating Systems and it was downloading. Is there not a way to hide this?

    • Paul,

      In response to your first question, I created a script that will accept a few parameters to modify the collection memberships.

      The next step was to create a status filter rule for the advertisement to run the script if it was successful.

      Here are the parameters for the status filter rule.

      General Tab
      Source: Client
      Message ID: 11171
      Property: Advertisement ID
      Property Value:

      Actions Tab
      Run a program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File \Set-DeviceCollections.ps1 -AddMember -AddToCollectionID “PS100ABA” -ComputerName %msgsys -RemoveFromCollectionID “PS100ABB”

      Someone else might have a better solution, but this works for me. I am also looking at using the ErrorReturnCode variable to add it to remediation collections when I need to upgrade/remove software.

      Hope this helps.

      • How is this being done currently? I have read all the blog posts, and successfully run the compat scan on my test computer (passed and cached the proper drivers). Now, I need to figure out how to move computers through the collections, but in the 20 or so blog posts, I haven’t found the solution. This comment is the first I’ve seen, but I can’t find the Set-DeviceCollections.ps1 in the provided waas files.

        • I haven’t blogged this (Automatically moving computers between deployments). The deployment of “How” is really depending on each org’s own polices, needs, requirements. While the WaaS Content I provide is generic enough for anyone to take parts from, the deployment / process itself is a bit more difficult. Currently we use a lot of powershell automation and direct memberships, not something I can share. I worked out a method in my personal lab of queries, but it can get a bit confusing, and I didn’t want to be on the hook to provide / answer questions about that aspect.

  10. New question or observation, I realized through my testing that I forgot to deploy a few driver packages and when the task sequence came up to the Set Dynamic Variables it found the correct system but when it was time to download the driver packages it failed.

    The only thing in the Registry under WaaS\1803 was “CS Started” and because the TS errored out nothing was written to WMI. Curious how you troubleshot failures on the workstations in your production environment when there is nothing to report on, or is the lack of reporting and systems still in the compatibility scan phase how you know to investigate issues.

  11. Another observation, in the CopyLogs section you reference %SMSTS_Build% but this variable has not been defined in your sequence so the script execution fails.

    You do however have Set OS Build Version in the sequence but the variable is osbuildversion.

    • Also shouldn’t the condition if the logs or copied or not be set to not equal 3247440400, assuming that value indicates a successful compat scan.

  12. Hi Gary,

    This is great information, thanks!
    I would like to know how do you prestage the OS image? I see that the steps are downloading the drivers packages, but what about the OS image & scripts/applications?

    Thanks a lot 🙂

    • This is all done by setting the two TS Variables in the beginning. Every package that is pulled down during the TS is stored in the CCMCache. So any packages referenced in the TS will be downloaded to the local cache to be available later.

  13. Great post Gary! I was able to create a pre-cache task sequence that successfully downloads the OS Upgrade image, specific drivers and other packages. However, when I run my IPU task sequence it’s still downloading from my DP (per logs) and not using the content in the ccmcache. Have you seen this? I have confirmed that I’m using the same package in both task sequences. Thanks for any help you can provide!

    • I’ve heard others say they had experienced this, but I have not. Did you confirm that the Drivers Package was downloaded into the CCMCache during PreCaching TS and that it matched the Version (no content change) when you run the steps in the IPU TS to download the drivers? I’ve since uploaded both my PreCache & IPU TS to my blog that you can download and see if anything pop out at you. I’m assuming you’ve tested running PreCache, then right after running the upgrade. Rest of the content is preserved in the CCM Cache though (Upgrade Media, Scripts, etc), just not the drivers?

      • Correct. I had confirmed all of the content was successfully downloaded to ccmcache and no content was changed from that point to running the IPU. Yep, I have tested by running the IPU right after the PreCache with the same results. I’ll keep looking into it and see if I can get an answer. Thanks for the quick response!

        • Did you happen to get this figured out? I too am seeing the same issue, downloads the content again but to the c:\smstasksequence folder.

  14. Thanks for the post.
    Why cant you use “Downlooad Package Content” step in the pre-cache TS with each step based on a WMI query of the HW model and deploy the TS as mandatory with Download only the content required?

    • If I’m following your line of thinking, that too should work, but you’d be adding a step per model you want to support vs just having a couple steps. It comes down to what works best for you.

  15. To answer Umakanth’s question – we prefer to configure the deployment to Download All Contents Before Starting the Task Sequence. This is much more bullet proof in an environment with lots of mobile devices that come and from the network. Keep in mind that this is a hidden TS that runs without the user’s knowledge. If you were to download content during the running TS and a user shuts down, reboots, etc. then you have a failed TS that needs to be fixed. By keeping the directly referenced content to what I like to call ‘the lowest common denominator’, you can pull all that down ahead of time. The downloading before will persist shutdowns, reboots, etc. Then the only thing that needs to come down during the TS is the driver package (even that we would like to evaluate and come down before hand).

    • I wanted to confirm this:
      If i lets say have “Download Package Content” steps for 5 hardware models and each step is based on HW model WMI and set the deployment to “Download all content before execution” then all the 5 packages will download correct?
      In your approach you are setting dynamic variables and recreating the “Download package content” using variables instead of the built-in step.

      This way you are not actually referencing the driver packages in the TS instead you are setting the PackageID based on the HW model WMI condition.

      This way though the TS is deployed as “Download all content before execution”, you are only downloading one driver package instead of five correct?


      • Correct, it only downloads the driver pack it needs because it’s not actually referenced in the TS. This also means that it will not download before it runs, because it would only download referenced items, hense we run a precache / compatscan TS, so it can download the drivers based on the variables in the middle of the TS running.

  16. Very interresant post. I want to upload content of Windows 10 upgrade like you describe before run the deployement. So the process you describe is exactly what i want. The 1rst TS with Precache works fine and content is placed at the end of the TS in C:\Windows\\CCMCache\xx. But, unfortunately, when i run the 2nd TS (upgrade), it download again all the content in C:\_SMSTaskSequence\Packages\PACKAGEID.

    Is there a possibility to keep content of previous TS in the C:\_SMSTaskSequence\Packages ?
    Or maybe there is something to change…

    • As long as your package versions haven’t changed, it should pull from the already downloaded ccmcache. Make sure you have your Upgrade TS set to “Download all content before starting”. It should then try to download all of the content before starting the TS, during that time, it will check to see if they are already in the CCMCACHE, and do hash checks if they are.

  17. How are your collections structured for the “PreCache” and “Upgrade” deployments?

    Do you have successful precache machines move OUT of the target collection so that the deployment is not run multiple times on “good” machines? If so, how is that accomplished?

    Likewise with the upgrade deployment; do you have successful upgrades move out of the target collection? Or do you change the re-run behavior in the deployment settings?

    Thank you!

    • I’ll let Gary answer in his way but this is what we are doing:

      -Create your servicing rings as collections (business requirements dictate membership)
      -Run your 1809 PreCache TS against those collections (or whatever version you’re using)
      -Create a Configuration Baseline for that version of Windows 10
      -Create collections based on compliance
      -If CS_SetupEngineReturn = No compatibility issues, one collection limited to every previous version of Windows 10 (i.e. NOT your latest version)
      -Once the upgrade runs, the machine falls out of the collection thanks to the limited collection from before.
      -Remediate issues of machines in non-compliant collection; after that’s fixed, the scan should show them compliant.
      -Upgrade those to Windows
      -Do this until you retire. 🙂

      Hope this helps! On Twitter, Mike Terrill described this as ‘internal telemetry’ and it’s exactly that. If you’re not using Upgrade Readiness (if not, why not?!), this works as well. It took me a little time to get it rolling but I’m pleased with the results.

  18. There is a step that fails for me,it’s the “SetOSDInfo PS” ( think it starts with Capture metrics)

    It is running this script: SetOSDInfo\Set-ComboInfo.ps1

    The parameters are these: -ID “%SMSTS_Build%” -WMI -Registry -Class “CompatScan” -Namespace “GARYTOWN”

    I’m not sure what Namespace is but I know mine wouldn’t be Garytown.

    However, the script is actually failing because at Line 643 there is a second “Else” in the script. So, it does an If, Else, then another Else.

  19. WaaS Module – Win 10 Customizations
    Tweak – Remove OneDrive App (Fails during TS – Set to continue on Error – 8/8/2016 – Doesn’t seem to be working. Need to investigate.)
    %SystemRoot%\SysWOW64\OneDriveSetup.exe /uninstall

    Mount the default user hive and delete this key
    reg delete HKEY_USERS\CUSTOM\Software\Microsoft\Windows\CurrentVersion\Run /v OneDriveSetup /f

    Just in case you haven’t gotten that resolved.

  20. I have questions too about Onedrive. We have O365 and I think more and more people will go in that direction. What about OneDrive and the 1TB we have? Some say to delete it with “OneDriveSetup /f” but we discovered Onedrive for Business will not work anymore when this command is applied.
    How do you manage it? There is some confusion 🙂

  21. This is great, and I want to implement this into our environment – however, we use driver automation instead of packages for each model. How can we pre-stage driver content and how does that change your TS here? I assume we could skip the “set dynamic variables” portion of the TS?

    • Sorry, I don’t have any experience with using that tool for deploying Drivers.. But as far I can understand, you’d have to completely change the method. You would have to have the tool download the driver pack to a static folder (C:\UpdatedDrivers), then during the upgrade, reference that location to get the drivers.

  22. Hello Gary,

    I can see for the drivers you have used in the dynamic variable step make and model for Dell.
    How about Lenovo?
    They have for a model not a real name, but rather digits.
    I have tried to get the gather.ps1 script to set model info, after that tried to use the variable returned from the script and seems it does not work well.
    Do you have any suggestion?

    • The Latest version of the Gather Script supports Lenovo. I’d recommend updating your script with the latest one which accounts for Lenovo.
      Do the Gather Step, dump the variables, then run a blank Set Dynamic Variable step, then dump the variables. Check what the “Model” is set to before and after the Set Dynamic Step as that might be updating it and breaking what is in the script… if that is the Case, on line 43, you could add something like:
      $TSvars.Add(“LenovoModel”, $tempModel)
      then use LenovoModel in the Set Dynamic Step to build out the Driver Package variables.

      Script: https://gallery.technet.microsoft.com/PowerShell-script-that-a8a7bdd8

      I have not tested any of what I’m suggesting, so be warned. 🙂

  23. Is there any way to only pre-download certain packages and have the deployment task skip downloading of those?

    We have low disk space issues where I am, but still could use some pre-downloading. But it looks like you have to set “download all content” in the deployment, which will more than double the amount of space I want to allocate to pre-downloading.

    Let me know if you have a way of doing this?


    • Do you have several additional items besides the Upgrade Media that you’re trying to Cache? You’d have to do it dynamically similar to how we do driver downloads. Drivers don’t download until during the precache TS run time.

  24. Probably a dumb question – but is there a good reason to use “Set Dynamic Variables” to handle the driver packages vs using a “Download package content” and saving the path to variable?

    I see that it’s nice it’s 1 line – but i found it a little nicer to see it clearly go into that step and return TRUE and download various packages for that model.

  25. Awesome work Gary “and Friends”! Question – is there a way I could set up just one PreCache TS to deploy many Version of Windows 10 (i.e. Professional, Enterprise, x64, x86) without having the machine precache ALL versions of Windows 10? That would take up a TON of drive space on the machines. Currently, I have to have 4 separate deployments to get this done.


    • Probably… you’d have to do something like what we do for Drivers. Map the PackageID of what you want to download, then call the download. You would NOT be able to run a compatibility scan then, as that would directly reference the media.

  26. Further to my comment just above, we are running into issues where we have to run the download of the drivers step a few times as they are getting hash errors. I see no rhym or reason to it, but even if i double up on the steps it will at times fail and thus the Upgrade step fails because the “%DRIVERS01%” has nothing. I had to actually put in a second OSupgrade without drivers just to deal with this.

    Any thoughts on this? I found a link indicating the running OSDDownloadContent.exe is not supported via command line.

  27. Thank you so much for this task sequence and in depth explanation of how this work. I ran into problem that compat scan failed to run due to install.wim is not in source folder. My install.wim is more than 4GB so I don’t know if that is a issue for downloading it to cache folder.
    Note that I am running this with Windows 10 2009.

    • You deploy it required, it runs silently. Once you deploy it required, it will start downloading on the endpoints before it starts, then during the task sequence running, it will cache the drivers.
      Running this TS is the caching portion of WaaS.


Leave a Reply to Mike Cancel reply

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