Windows 10 Feature Updates – Testing the /MigNEO Disable Parameter

Over the past few weeks I’ve been testing re-writing my Windows 10 Feature Update repo to make it easier to implement - if you haven’t tried it, go check it out. Just follow the readme in the repo https://github.com/AdamGrossTX/Windows10FeatureUpdates. During the re-write I was reminded that there were a few command line parameters that I hadn’t experimented with. One of them is /MigNEO which only has a Disable option. According to the product group, NEO stands for non-event objective which, doesn’t help it make more sense to me. Anyway, MigNEO is designed to give IT Admins more control over how Feature Updates are applied. Windows Setup Command-Line Options | Microsoft Docs

The default behavior of Feature Updates since 1803 is to perform MOST of the upgrade operations while the device is still in use. You may see this referred to as Downlevel/Online Time/Online Phase, etc. It means that the Feature Update can be processing the upgrade while the user is still working with a shorter Offline time where the device is applying the update and unusable. /MigNEO Disable removes this optimization and performs more actions during the Offline phases with a much shorter Downlevel/Online time. See the troubleshooting docs for info on each phase Troubleshoot Windows 10 upgrade errors - Windows IT Pro - Windows Deployment | Microsoft Docs.

Upgrade process

Comparison Tests


Note: All tests were done on clean VMs with no apps or data to migrate. Real-world results may vary.


I decided that I needed to test /MigNEO Disable and see what the difference was really like and built 6 Hyper-V VMs (2 each with 1909, 1809, 1709) and upgraded them to 2004 using the 2004 ISO media. Each upgrade used the initial release version of 2004 so that the devices would also download Dynamic Updates during the process. I ran the tests several different times and the results were pretty consistent. I attempted to run all 6 VMs at the same time, and while it worked, the upgrades took about 1.5hrs to complete so I switched to just running 2 at a time and they completed in under 45 minutes.

Here are the command lines that I used. You could also use SetupConfig.ini for this, I just used the command line for quick testing:

1
2
3
d:\setup.exe /auto upgrade /quiet /compat ignorewarning /diagnosticprompt enable /priority high /showoobe none /migneo Disable

d:\setup.exe /auto upgrade /quiet /compat ignorewarning /diagnosticprompt enable /priority high /showoobe none

I recorded the upgrades and uploaded them for your viewing pleasure. It is literally 50 minutes of feature updates in realtime. I added milestone text in the videos so you should be able to scroll through and see the text change.

The results were interesting. All of the machines with /MigNEO Disable rebooted around the 8 minute mark. while the default machines rebooted between 29-34 minutes. That means that the users would have been able to work for ~25 minutes longer before the first reboot than with /MigNEO Disable.

The key takeaway for me here was that using the default setting, the devices were offline for under 7 minutes, compared to up to 30 minutes when disabled!

A Square Dozen Image

So which is better?

As I was testing, I kept wondering why anyone would want to disable the optimizations and cause users to be offline for so long. I got some feedback on Twitter as well as from the product team on why this option is useful. https://twitter.com/AdamGrossTX/status/1303079790921080833?s=20

According to the product team:
By default NEO is enabled. So we spend more time down level with lower priority and if you have other install tasks while pending reboot, the staged feature update gets invalidated and you end up spending more time offline also. So MigNEO was added to give more control to you.

Gary Blok brought up an interesting point as well. Applying the upgrade with a task sequence from ConfigMgr, if something happens during the Downlevel phase and task sequence fails, it is difficult to get the ConfigMgr client back online and/or restart the task sequence, so having a short offline time is more desirable in this case as well. On the Task Sequence note, you should be able to add /MigNEO Disable to your ConfigMgr Task Sequence if you are using one. See OSDSetupAdditionalUpgradeOptions in the docs Task sequence variable reference - Configuration Manager | Microsoft Docs for more info. Johan Arwidmark has a great blog on using it as well Specify additional command-line options to Setup during a Windows 10 upgrade when using ConfigMgr - Deployment Research (deploymentresearch.com). My guess would be that your TS would reboot into the Safe OS phase within 8 mins of starting the Upgrade Operating System step, instead of 30+ mins of sitting in Windows watching the progress dialog.

Digging Deeper

If you’ve ever looked through setupact.log, you’ll know that it has a TON of info and can be daunting to dig through. I attempted to find references to MigNEO in the logs and pull out relevant bits. Here are a few entries that give us clues about whether NEO is in use or not. (Copy to notepad for easier viewing then search for NEO to see the entries.)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
2020-09-07 09:48:03, Info                  MOUPG  SetupHost::Initialize: CmdLine                = [/Install /Media /Quiet  /InstallFile "d:\Sources\Install.wim" "/auto" "Upgrade" "/compat" "ignorewarning" "/diagnosticprompt" "enable" "/priority" "high" "/showoobe" "none" /MediaPath "d:"]

2020-09-07 09:50:13, Info                  MOUPG  SetupManager: Uninstall Enabled via host OS version.
2020-09-07 09:50:13, Info                  MOUPG  SetupManager: NEO Enabled via scenario detection.
2020-09-07 09:50:13, Info                  MOUPG  SetupManager: Rollback Enabled via scenario detection.

2020-09-07 09:50:13, Info                  SP     We are not low on disk space, scratch space will not be used.
2020-09-07 09:50:13, Info                  SP     NEO installation path is allowed.
2020-09-07 09:50:13, Info                  SP     Storage Reserve is ignored by external request
2020-09-07 09:50:13, Info                         Onesettings: Querying Prod server

2020-09-07 09:50:14, Info                  MOUPG  SetupManager: CompactOS Disabled via cached policy detection.
2020-09-07 09:50:14, Info                  MOUPG  SetupManager: Uninstall Enabled via host OS version.
2020-09-07 09:50:14, Info                  MOUPG  SetupManager: NEO Enabled via scenario detection.
2020-09-07 09:50:14, Info                  MOUPG  SetupManager: No BitLocker command line option specified, will try to keep active but suspend on errors
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2020-09-07 09:48:05, Info                  MOUPG  SetupHost::Initialize: CmdLine                = [/Install /Media /Quiet  /InstallFile "d:\Sources\Install.wim" "/auto" "Upgrade" "/compat" "ignorewarning" "/diagnosticprompt" "enable" "/priority" "high" "/showoobe" "none" "/migneo" "Disable" /MediaPath "d:"]

2020-09-07 09:48:07, Info                  MOUPG  SetupManager: DiagnosticPrompt Enabled via override.
2020-09-07 09:48:07, Info                  MOUPG  SetupManager: PartitionResize Enabled by default.
2020-09-07 09:48:07, Info                  MOUPG  SetupManager: NEO Constraint set via override: [-1].
2020-09-07 09:48:07, Info                  MOUPG  SetupManager: Target Drive Letter set to [C] via default.

2020-09-07 09:50:29, Info                  SP     We are not low on disk space, scratch space will not be used.
2020-09-07 09:50:29, Info                  SP     NEO installation path is turned off by external request
2020-09-07 09:50:29, Info                  SP     Storage Reserve is ignored by external request
2020-09-07 09:50:29, Info                         Onesettings: Querying Prod server
2020-09-07 09:50:29, Info                  SP     Get Upgrade snapshot policy Onesetting 0
2020-09-07 09:50:29, Info                         Set Watson bucketing parameter #6 to 17763
2020-09-07 09:50:29, Info                         CDiagnosticsHelper::set_WatsonEventName: Get NULL for WatsonEventName
2020-09-07 09:50:29, Info                         Set Watson bucketing parameter #8 to 19041
2020-09-07 09:50:29, Info                         Set Watson bucketing parameter #2 to 9
2020-09-07 09:50:29, Info                         Set Watson bucketing parameter #9 to vb_release
2020-09-07 09:50:29, Info                  SP     WIM file is not local, copying it to the sources directory
2020-09-07 09:50:29, Info                  SP     OPERATIONTRACK: Enqueue Operation:   4|Copy source WIM file to the sources directory
2020-09-07 09:50:29, Info                  SP     We will also remove it as soon as we finish the apply operation.
2020-09-07 09:50:29, Info                  SP     OPERATIONTRACK: Enqueue Operation:  38|Apply WIM file PathForNewOSFile, index 3 to C:\$WINDOWS.~BT\NewOS
2020-09-07 09:50:29, Info                  SP     Neo installation path is turned off, pushing WIM apply to SafeOS phase
2020-09-07 09:50:29, Info                  SP     Cleanup operation "Cleanup source WIM file(s)" will cleanup:
2020-09-07 09:50:29, Info                  SP       PathID: PathForNewOSFile
2020-09-07 09:50:29, Info                  SP     OPERATIONTRACK: Enqueue Operation:  66|Cleanup source WIM file(s)
2020-09-07 09:50:29, Info                  SP     OPERATIONTRACK: Enqueue Operation:  41|Complete new OS apply
2020-09-07 09:50:29, Info                         Onesettings: Querying Prod server

Summary

For our environment, we’ve found that using the default (NEO enabled) is optimal. It reduces user downtime and is almost a non-event for most users. The upgrades take almost the same time with either setting, so choose the option that fits your needs best.