
- Technical support of any issue
- Software updates
- Security updates or fixes
Therefore I´ve created a Blogpost on how to check against Windows 11 readiness using a Microsoft provided Powershell Script and Symantec´s Client Management Suite Custom Inventory. While this still is a valid way to check against Windows 11 Readiness there is another option to check against Windows 11 Readiness using the Registry. In this Blogpost I´ll provide information on how to consume this data and report on it.
The Microsoft provided Powershell Script is limited to check against the Windows 11 Hardware Requirements while this is very good there are also „other“ Requirements to check against.
This method descriped here is a combination of the Microsoft provided Powershell Script and the Method for checking other Requirements that the Powershell Script is not capable.
The excellent news is that you can check readiness against Windows 11 using both methodes when using Symantec´s Client Management Suite custom inventory.
When using this method you can also check against a list of apps and drivers that are blocked these is not covered by the Microsoft PowerShell Script, so we must find another way to check against this..
Prerequisites
- Basic Telemetry data needs to be enabled
- The Microsoft Appraiser scheduled task must be enabled
Using Group Policies for Windows 10 and Windows 11 to enable Basic Telemetry data
Windows 10:
Computer Configuration\Administrative Templates\Windows Components\Data Collection and Preview Builds\Allow Telemetry - Enabled and set to set to 1 - Basic
Windows 11:
Computer Configuration > Administrative Templates > Windows Components > Data Collection and Preview Builds > Allow Diagnostic Data - Enabled and set to (1) Send required diagnostic data
Setting these GPOs creates the registry DWORD:
HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection, DWORD: AllowTelemetry, value=1
If you have a GPO that disables Telemetry Data in your Environment and you can run the following Powershell Script to populate the Data into the Device Registry – to be later caputured by Symantec Custom Inventory. The GPO then reverts back the regkey.
#Enable Basic Telemetry Data in the Registry
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection' -Name 'AllowTelemetry' -Value '1'
#Run the Microsoft Appraiser Scheduled Task
Start-ScheduledTask -TaskPath "\Microsoft\Windows\Application Experience"-TaskName "Microsoft Compatibility Appraiser"
#Wait 30 Seconds
Start-Sleep -Seconds 30
Registry Method for Windows 11 Readiness Check
When the registry key is set and the Scheduled Task is finished you will see the Data in the Registry. We are interessed in multiple keys but mainly focus on the GatedBlockID if not „None„.
This is the Safe Guard Hold ID.
Microsoft uses quality and compatibility data to identify issues that might cause a Windows client feature update to fail or roll back. When we find such an issue, we might apply safeguard holds to the updating service to prevent affected devices from installing the update in order to safeguard them from these experiences.
Where can you find the Safe Guard Hold on your device? In the Registry!
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\TargetVersionUpgradeExperienceIndicators

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\CompatMarkers

These Registry values can be gathered by Custom Inventory and later reported on.
Scheduled Task for Compatibility Check

Create Custom Inventory Dataclass with Attributes

Custom Inventory Powershell Script
Powershell Script to capture the required Information from the Registry.
#************************DO NOT EDIT********************************
$nse = new-object -comobject Altiris.AeXNSEvent
$nse.priority = 1
$nse.To = "{1592B913-72F3-4C36-91D2-D4EDA21D2F96}"
#************************DO NOT EDIT********************************
#Modify this varaible with the custom data class guid
$DataClassGuid = "{5b855d5e-e480-4c0e-b386-11ea5d2f5b6b}"
$objDCInstance = $nse.AddDataClass($DataClassGuid)
$objDataClass = $nse.AddDataBlock($objDCInstance)
$regPathTVEI = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\TargetVersionUpgradeExperienceIndicators\GE24H2"
$regPathCM = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\CompatMarkers\GE24H2"
$regValuesTVEI = Get-ItemProperty -Path $regPathTVEI
$regValuesCM = Get-ItemProperty -Path $regPathCM
####Add new row of data
$objDataRow = $objDataClass.AddRow()
###Single Values
#$($regValuesTVEI).GatedBlockId
#$($regValuesCM).BlockedByBios
#$regValuesTVEI.RedReason
$objDataRow.SetField(0, [STRING]$regValuesTVEI.GatedBlockId)
$objDataRow.SetField(1, [STRING]$regValuesTVEI.GatedBlockReason)
$objDataRow.SetField(2, [STRING]$regValuesTVEI.RedReason)
$objDataRow.SetField(3, [STRING]$regValuesTVEI.UpgEx)
$objDataRow.SetField(4, [STRING]$regValuesTVEI.UpgExU)
$objDataRow.SetField(5, [STRING]$regValuesCM.BlockedByBdd)
$objDataRow.SetField(6, [STRING]$regValuesCM.BlockedByBios)
$objDataRow.SetField(7, [STRING]$regValuesCM.BlockedByCloverTrail)
$objDataRow.SetField(8, [STRING]$regValuesCM.BlockedByComputerHardwareId)
$objDataRow.SetField(9, [STRING]$regValuesCM.BlockedByCpu)
$objDataRow.SetField(10, [STRING]$regValuesCM.BlockedByCpuFms)
$objDataRow.SetField(11, [STRING]$regValuesCM.BlockedByDeviceBlock)
$objDataRow.SetField(12, [STRING]$regValuesCM.BlockedByHardDiskController)
$objDataRow.SetField(13, [STRING]$regValuesCM.BlockedByMemory)
$objDataRow.SetField(14, [STRING]$regValuesCM.BlockedByNetwork)
$objDataRow.SetField(15, [STRING]$regValuesCM.BlockedBySModeState)
$objDataRow.SetField(16, [STRING]$regValuesCM.BlockedBySystemDriveSize)
$objDataRow.SetField(17, [STRING]$regValuesCM.BlockedByTpmVersion)
$objDataRow.SetField(18, [STRING]$regValuesCM.BlockedByUefiSecureBoot)
$objDataRow.SetField(19, [STRING]$regValuesCM.BlockedByUpgradableBios)
$objDataRow.SetField(20, [STRING]$regValuesCM.UexRatingOrange)
$objDataRow.SetField(21, [STRING]$regValuesCM.UexRatingRed)
$objDataRow.SetField(22, [STRING]$regValuesCM.UexRatingYellow)
$objDataRow.SetField(23, [STRING]$regValuesCM.UexUsageRatingOrange)
$objDataRow.SetField(24, [STRING]$regValuesCM.UexUsageRatingYellow)
#Send the data
$nse.sendqueued()
Additional Information on Registry Entries
Other interesting Regkeys are the GatedBlockReason, the RedReason, and the UpgEx and the UpExU. Here you can find a detailed description.
If there is a block, you will see a GatedBlockID with a number listed in the REG_MULTI_SZ. With this number, you can check against a source-crowded SafeGuard Database that will give you the full details of the block.
This Powershell Script with the Database / JSON to check for the SafeGuard Hold is provided by Gary Blok
References
Gary Blok: https://garytown.com/
Broadcom Article: Windows 11 Readiness Custom Inventory and Report
*Microsoft: Windows 10 supports ends on October 14, 2025