Disclaimer - if you manually bypass Feature Update blocks, you risk causing issues with your device. The blocks exist for a reason and should be respected. This information is provided for educational purposes only. Proceed with caution.
Windows 10 Feature Updates are released twice per year. For each release, Microsoft has the ability to block the update from being installed or even showing up in Widows Update for applications/drivers/devices that have known compatibility issues. This is a pretty great feature since it helps prevent unnecessary failures for already known issues that Microsoft is possibly already working to address. The flaw in this feature is the lack of visibility into what is being blocked and how/when it should be unblocked. Microsoft has gotten a little better with this area by keeping this site updated https://docs.microsoft.com/windows/release-information/status-windows-10-2004, however from a client installation perspective, it is often difficult or even impossible to match up an error message/code with anything published on that site (or any other Microsoft site). When Windows 10 2004 was released, there was a block in place for certain hardware models including the Surface line. When your boss has a Surface Pro 7 that can’t upgrade to the latest feature update, you’re not going to have a good time. This post is a deep dive into my experience with identifying Hard Blocks and making sense out of generic error messages like the one below. It will also contain some best guesses for how some things work where I may not have a 100% clear understanding.
Last things First
After writing this, I realized that I have crammed a lot if stuff in here. I want to highlight the main points to keep things from getting lost in the pile.
- Gain a better understanding of Feature Update blocks that prevent devices from upgrading - sometimes blocking the update from even showing up on the device as available.
- Understand how to manually convert Appraiser results to XML then compare to the Windows Compatibility Database (appraiser.sdb).
- Automate the collection and assessment of Feature Update blocks using custom PowerShell module FU.WhyAmIBlocked.
Blocked Upgrade Messages
When Windows 10 2004 shipped, the internet filled up with reports of people getting messages indicating that their devices couldn’t be upgraded. Everyone was asking - ‘Why am I blocked?’. Presenting a message telling us that we are blocked, but providing no actionable information is less than helpful. This needs to improve.
This PC can’t be upgraded to Windows 10
Let’s start with this message. It is very generic and less than helpful. It can appear in the setup UI if you are manually running setup.exe
or in c:\$WINDOWS.~BT\Sources\Panther\ActionableReport.html
.
|
|
…Your device isn’t quite ready for it…
On these same devices, if you attempt to pull the feature update from Windows Update, you may see a message like this one that showed up for Windows 10 2004.
|
|
CompatData Hard Block
When a Feature Update fails to install, you can generally check in the last CompatData_*.xml file for information about the failure. Unfortunately, sometimes the information is vague.
|
|
ConfigMgr and Desktop Analytics
If you are an enterprise customer and are fortunate enough to use ConfigMgr, you can leverage Desktop Analytics to assess device and app compatibility BEFORE attempting to install feature updates. We have been using this (And Windows Analytics before DA) since it was released and it has almost eliminated the need for testing ALL of our applications before deploying the latest Feature Update - we still test critical apps. The shortcoming with DA is that is simply reports back what the Microsoft Compatibility Appraiser reports. It doesn’t include details specific to the blocking app. Work is still being done with DA, so I think there’s hope for integrating more data in the future.
Microsoft Compatibility Appraiser
So, I mentioned the Microsoft Compatibility Appraiser in the previous section. Whether you are aware of it or not, your Windows 10 device is actively assessing your device’s compatibility with Windows releases (possibly other monthly updates as well). I’ll break down the pieces that I have put together, but I still feel like this a ‘black box’ that I don’t fully understand.
CompatTelRunner Scheduled Task
Open Task Scheduler and you will find the Microsoft Compatibility Appraiser
task under Task Scheduler Library>Microsoft>Windows>Application Experience
This task launches:
%windir%\system32\compattelrunner.exe
which in turn launches:
%windir%\system32\CompatTelRunner.exe -m:appraiser.dll -f:DoScheduledTelemetryRun
The output of this task produces a set of registry entries as well as some output files (possibly others that I’ve missed):
These .bin files that are generated contain a list of compatibility assessment results. Portions of the results are also listed in the registry. For example, if there are hard blocks, a SdbAppGUID will be listed in the .bin file and a corresponding entry will be listed in the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Appraiser\GWX\SdbEntries
Since the entries are in the registry, you can easily use ConfigMgr’s CMPivot tool to query the values to determine which SdbAppGUIDs are causing blocks using this CMPivot query:
|
|
Compattelrunner.exe
also checked for any policies you may have enabled that prevent updates.
Appraiser.sdb and Alternate Appraiser Data
The appraiser consumes a database of info from Appraiser.sdb
and uses a task list file Appraiser_TelemetryRunList.xml
to tell it what to process. The default location of these files is C:\Windows\System32\appraiser
.
If a machine is not on the latest Feature Update, compattelrunner.exe
will download an Alternate_AppraiserData.cab
file to c:\Windows\appcompat\appraiser
from http://adl.windows.com/appraiseradl/YYYY_DD_MM_??_??_ARCH.CAB
Here’s a list of cab files that I’ve been able to find by looking at setupact.log files and searching the internet for other people’s logs. I don’t know where the current URL comes from to tell the client which file to get nor do I know what the last 2 sets of numbers stand for. I was thinking they may be HH_MM but that doesn’t seem to line up every time.
|
|
You can read more about data sharing and this URL here: https://docs.microsoft.com/mem/configmgr/desktop-analytics/enable-data-sharing. Be sure that you allow clients to access the listed URLs or you may experience issues with updates not having the latest compatibility information. When you expand the cab files using, you will get the following contents:
These files are the key to understanding why machines will be blocked one day then unblocked the next and why you may experience different results on the same devices.
Dynamic Updates
If you disable Dynamic Updates or prevent your devices from going to the URLs listed above, you run the risk of preventing your devices from being able to install the latest Feature Update or install it properly. Whenever Windows setup runs, it will run a customized compatibility assessment and will download the latest Alternate_AppraiserData.cab files. This ensure that it has the latest compatibility information to assess a device against and provides a list of current migration shims that may mean the difference between success or failure of the upgrade.
Setupact.log
During or after a Feature Update, the setupact.log shows where it goes out to get the latest cab then runs a compatibility assessment. This one of several compatibility checks that are performed.
|
|
Just as the CompatTelRunner scheduled task will create new bin files, the process during Windows Setup will create a set of XML and BIN files in the Panther folder.
Appraiser_TelemetryRunList.xml
The Appraiser_TelemetryRunList.xml file tells the appraiser which actions to perform. It also tells it which sdb to use and where to output results of each scan. You could compare this xml to the xml files output during Windows setup and match up the components. I haven’t gotten that far into it. The module included at the end here has PowerShell to generate your own RunList.
Force a new Appraiser.sdb to process
During testing, I was able to replace the current Appraiser_AlternateData.cab file with an older version and run the scheduled task and the old file would be used. This is because the registry key logs which files were used last. If the key isn’t updated or deleted, a new file won’t be downloaded. Comparing Appraiser_Data.ini with the registry key you can determine if the device has used the current database.
I was also able to delete the Appraiser_AlternateData.cab from C:\Windows\appcompat\appraiser and re-run the scheduled task and it would pull down the latest version.
Deserialize Appraiser BIN files
The output of the appraiser process will be a .bin file (and during a feature update an .xml file). The bin file is just a binary XML file that can be converted by using the appraiser process. It’s a configuration option built into the RunList XML. Here’s an example XML file that will take the file C:\Windows\appcompat\appraiser\APPRAISER_TelemetryBaseline_20H1.bin
and deserialize it into the XML file APPRAISER_TelemetryBaseline_20H1_HUMANREADABLE.xml
|
|
Run this in a cmd prompt and point to your RunList.
rundll32.exe appraiser.dll,RunTest MyRunList.xml
I used this script from Technet gallery (which will be going away soon) to get started down this process. It appears to be maintained by someone from the Microsoft CSS team but I’m not sure. https://gallery.technet.microsoft.com/scriptcenter/APPRAISE-APPRAISERbin-to-8399c0ee
*HumanReadable.XML
In the screenshot below of the Windows Panther folder, you’ll see bin and xml files. These files were generated during a Feature Update and you’ll see that they are already in XML format. From my experience, I’ve found that the second entry is the one that will generally contain block information. They correspond to the bin files that we see in the appraiser folder. There will be an *_UNV.bin
and one that corresponds to the Windows release like *_20H1.bin
. Likewise, the files created during setup appear to be broken out the same way.
An example of a device that’s blocked by an entry in one of these files would look like this. This is from the appraiser output folder, not a Feature Update. Search the file for the BlockingMatchingInfo
property to find blocks.
|
|
Here’s another example of the block generated during a Feature Update. The main differences are 1) there are 2 blocks in the first example 2) the feature update blocks render out the GenericMessage text where the appraiser version just points to a Resource ID.
|
|
The entries are grouped by Name, so you have to follow the Ordinal values. All Ordinal = "1"
entries belong to the same block. In this case we can see that this device has 2 blocks for OneDrive and Legacy filters
. Not all entries listed in this section will be hard blocks but it’s a good place to start.
What the Heck is OneDrive and Legacy filters?!?
In my search to find answers, the OneDrive and Legacy filters block has been the thing that I just didn’t understand. If you list an app or hardware model in the block, that makes sense, but this one was so vague that it drove me to dig deeper.
I had a hunch that the info I needed would be in the appraiser.sdb files. After some digging around and lots of trial and error, I found 2 tools that ultimately helped convert the Compatibility Appraiser Database to XML.
https://github.com/TheEragon/SdbUnpacker - Python script to decompress the sdb.
https://devblogs.microsoft.com/setup/shim-database-to-xml - EXE to convert from sdb format to XML using the SDB API.
Once I had extracted the SDB into XML. I was able to match the GUIDs from the appraiser bin files with entries in the database. Each entry lists the files and registry keys that are used to determine if something should be blocked. In my case, there were 4 relevant entries related to OneDrive and Legacy filters
.
|
|
From this entry, we can see that the appraiser is looking for the existence of registry keys. If they exit, it will block the upgrade and display messaged tied to the IDs listed in the BLOCK_UPGRADE section. Once I removed the registry keys for all of the blocks and re-ran the appraiser, the blocks went away and I was able to apply the Feature Update.
|
|
While I was in the sdb, I discovered another registry key that allowed me to bypass the block without actually deleting registry keys that may be critical to the app causing the block.
Once I created the regkeys and re-ran the appraiser, the blocks were still listed, but new entries appeared referencing the BypassBlockUpgrade keys.
Here’s another example where the Surface Pro 7 was blocked for 2004. This one gets a bit tricky. The first image show 2 GUIDs that match the GUIDs for a MACHINE_BLOCK in the 4th image. The second image shows the SdbEntryGuid that matches the MATCHING_INFO_BLOCK in the 3rd image. You’ll also see the registry key to bypass the block in the 3rd image. This whole time, we could have bypassed the Surface Pro 7 block!!!
FU.WhyAmIBlocked Powershell Module
FU is short for Feature Update
After going through all of this, I decided that this was too many steps to perform on a per-machine basis, so I took everything and created a new PowerShell module to help. Detailed usage info and updates can be found on the GitHub project site https://github.com/AdamGrossTX/FU.WhyAmIBlocked.
It has been published to the PowerShell Gallery (My first one, thanks Ben!) and you can install it directly on any machine you need to troubleshoot. https://www.powershellgallery.com/packages/FU.WhyAmIBlocked
In order to process the database SDB files, you will need Python installed. I have tested with Python 3.8 using the msi installer or the Windows Store app (which is pretty sweet!).
Also, I was limited on the block scenarios that I could replicate in my environment so results and match text files may not show everything. I suggest manually searching the appraiser.sdb.XML file for additional entries.
|
|
Assessing your Compatibility Blocks at Scale
Here’s what I did to assess my environment:
- Collect SDB Block GUIDS and SDB Versions from the Registry using CMPivot
- Export results to CSV and get a distinct GUID list
- Process GUIDs against Appraiser.sdb.xml
|
|
This should produce a Matches.txt file that you can use to review all of your enterprise’s blocks without having to collect any additional client information.
Summary
I feel like I’ve covered all of the pieces of the puzzle that I’ve put together at this point. I don’t think I’m finished with this process or the module, but needed to get this first round of info out of my head before I lose it. I’d love to hear your thoughts and get feedback on the module.
References
- sdbUnpacker - https://github.com/TheEragon/SdbUnpacker
- sdb2xml - https://devblogs.microsoft.com/setup/shim-database-to-xml/
- Shim Database API - https://docs.microsoft.com/windows/win32/devnotes/application-compatibility-database?redirectedfrom=MSDN
- Get-SDBFileInfo.ps1 - https://github.com/cinglis-msft/UpdateComplianceConfigurationScript/blob/1ab7c920ea81b86a1b36c698027c8fb8fdd064d5/Pilot/Diagnostics/Get-SdbFileInfo.ps1
- CSSAPRS - https://gallery.technet.microsoft.com/scriptcenter/APPRAISE-APPRAISERbin-to-8399c0ee
- AppRPS script. May be a predecessor to the one above - https://aka.ms/AppRPS
Addendum
After posting this, I got a message from Trevor Jones pointing me to a Microsoft doc with a buried registry key to bypass any data collection compatibly checks for Feature Updates. https://docs.microsoft.com/windows/deployment/update/update-compliance-feature-update-status#opting-out-of-compatibility-hold
Here’s the text from that post in case it ever goes away:
Compatibility holds
Microsoft uses diagnostic data to determine whether devices that use Windows Update are ready for a feature update in order to ensure a smooth experience. When Microsoft determines a device is not ready to update due to a known issue, a compatibility hold is generated to delay the device’s upgrade and safeguard the end-user experience. Holds are released over time as diagnostic data is analyzed and fixes are addressed. Details are provided on some, but not all compatibility holds on the Windows 10 release information page for any given release.
Opting out of compatibility hold
Microsoft will release a device from a compatibility hold when it has determined it can safely and smoothly install a feature update, but you are ultimately in control of your devices and can opt out if desired. To opt out, set the registry key HKLM\Software\Microsoft\Windows NT\CurrentVersion\502505fe-762c-4e80-911e-0c3fa4c63fb0
to a name of DataRequireGatedScanForFeatureUpdates
and a value of ``.
Setting this registry key to 0 will force the device to opt out from all compatibility holds. Any other value, or deleting the key, will resume compatibility protection on the device.
I will test this when I get some time and see if how it behaves compared to the other options mentioned. Thanks Trevor!