TPM errors in Windows 11

The last several machines I’ve built–and several long-running machines with nothing wrong with them–have suddenly started displaying strange errors regarding Microsoft 365. The affected machines can neither register Office365 apps to the entire machine successfully, nor will they accept user logins to the Outlook desktop app.

Although you don’t get any obvious errors when Outlook refuses to accept a valid password–confirmed by entering the same password successfully to log into Outlook on the Web in the same machine’s browser–scouring Event Viewer carefully enough will lead you to notice TPM related warnings and errors in the System log, occurring each time you attempt to log into desktop Outlook or attempt to register Office365 apps globally.

The extremely poorly documented actual fix requires at least one and sometimes up to three steps, followed by a reboot. If you want to perform all three steps pre-emptively then reboot, fine–but if you find you need to perform more steps, please realize you will need to reboot again following those additional steps!

Step one: regedit

First, you need to update two registry keys (you may save this text as a .reg file and add it to your Registry directly; the key names have been the same on the ten or so machines I’ve fixed in the last several weeks, despite looking like there might be GUIDs there):

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Common\Identity\Identities]
"EnableADAL"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Protect\Providers\df9d8cd0-1501-11d1-8c7a-00c04fc297eb]
"ProtectionPolicy"=dword:00000001

Step two: (DANGER!) clear TPM (DANGER!)

Next, consider deleting the values currently stored in your TPM. 

WARNING WARNING WARNING: if you are using Bitlocker, make certain you will still be able to decrypt the drive after destroying the secrets in your TPM! At a minimum, this means making sure you’ve got scratch codes available. If you don’t have a full backup available that you are prepared and ready to use, strongly consider decrypting the drive before destroying the data in your TPM–if you turn out not to have the scratch codes, or have the wrong scratch codes, etc etc etc, there is no turning back.

If you have decided to go ahead and clear out your TPM now, click Start, type in tpm.msc, and hit Enter. The TPM settings dialog will pop up. Click “clear TPM.” 

Again, do not blindly clear your TPM if you are using BitLocker!

Once you have decided whether or not to pre-emptively clear your TPM, reboot the system, and check to see if your Microsoft 365 woes have been resolved. If they have not, and you haven’t cleared the TPM yet, you’ll need to make arrangements to ensure safety of your data, then clear the TPM, reboot once more, and try again.

If you still have no joy after completing both steps one and two and rebooting, it’s unfortunately time for the last and most obnoxious step.

Step three: create a new, clean Windows user profile

If you’ve added the registry keys and manually cleared the TPM, then rebooted, and your Microsoft 365 login and registration problems still aren’t fixed, the problem is very likely in an undiagnosed area of your user profile.

I only needed to perform this step on two of the ten or so machines I’ve resolved these TPM errors on in the last few weeks–but on those two machines, there was no getting around it; the whole user profile had to go.

The good news is, you can test whether this is necessary before actually destroying anything! Create a new local user on your system (or log in with a different domain user which has never logged into the local system, in an Active Directory environment), log out as the current user, and log in as the brand-new user profile.

Now, try to first activate Office365, then set up Outlook to access the affected user’s email. If you already completed steps one and two, this attempt should succeed with no issues. Once you’ve successfully both registered Office 365 to the affected user’s email account, and successfully logged into that user’s email account in desktop Outlook, you know your problem really was in the original Windows user profile.

At this point, you can do one of three things. You can:

  • Either continue setting up the new Windows profile for regular use, move the user’s data to the new profile, then destroy the old profile
  • Or you can back up the user’s data, destroy the user’s old profile, create a new profile with the same username / log into Active Directory with the same user credentials, then restore the user’s data
  • Or you can get out your Mad Scientist toolkit and start feverishly trying to analyze the broken profile and figure out why it’s broken (I have had no luck with this approach, myself).

Conclusion

I don’t know what’s going on at Microsoft right now, but these TPM errors have been a plague for quite a while, and Microsoft keeps failing to either fix the issue or even provide the sort of comprehensive workaround I’m documenting here.

The good news is, despite needing to fix ten or so machines and counting so far, the majority of the affected machines were fine after nothing but Step 1 (add registry keys) and a reboot, and most of the rest were okay with only adding Step 2 (clear TPM values) and a reboot.

Again, I beg, plead, warn, scream at you: do not blindly clear the TPM without considering the impact on associated services, especially BitLocker.

Finally, of the two machines that still refused to work properly after clearing the TPM, Step 3 (blowing away the user’s Windows profile, then either manually recreating it from scratch or logging in again into an AD environment to recreate it from scratch) worked a treat.

So far, I have not encountered any machine that wouldn’t resume O365 functionality after following this guide. (Knock on wood). Good luck, fellow sysadmin or helldesk veteran, and may the Force be with you…

And please, please, please do not blindly clear the TPM without considering the consequences to associated services such as but not limited to BitLocker!

Re-targeting existing .NET apps to a specific runtime version

File under “wow, I had no idea you could even do that”… also, file under “you really shouldn’t have to do that,” but that’s another story.

CPA clients are always an interesting challenge. By the standards of the IT world, their applications are really pretty simple and they don’t have a lot of data to deal with… but unfortunately, the tax codes they have to model were designed for human clerks physically stamping and filing papers in actual filing cabinets, not for modern data storage. Worse, those same tax codes vary from year to year, in arbitrary ways that seem “simple” from a human perspective but are difficult to fit into a logical framework. The end result is, your poor accountant has to deal with software that’s actually re-written once a year, every year, rather than a sane, logical framework that just gets a few variables tweaked from time to time.

Needless to say, quality control on this kind of software is frequently not all that it could be. In one particular case, a client was using an application called TaxWorks. The client has a nice, modern firm with a Windows Terminal Server for all of his accountants to do their work in. Doing it this way lets him (and me!) maintain the bewildering array of niche applications a CPA needs on a single machine, rather than having to keep them installed and updated across an entire network of workstations. For the most part, this is a great thing… but unfortunately, the folks who write TaxWorks apparently never did too much testing on any Windows Server platforms; the application works fine on Windows XP, and at first it worked fine on Server 2003 R2… until one day, my client called me and said TaxWorks just quit working. Which it did; the app would start but then would hang in several places. Many many hours of troubleshooting and many many calls to technical support later, we finally got to the root of the problem: on XP, TaxWorks works fine. But on Server 2003, TaxWorks stops working if any version of the .NET framework later than 2.0 gets installed.

For a while, we got by just avoiding installing .NET 3.0 and 3.5 from Windows Updates; but eventually, of course, one of the other applications on the server actually required .NET 3.5. The good news is, it turns out that even if you’re not the developer of a particular .NET app, you can target it to a specific version of the .NET runtime after-the-fact. It’s not particularly well documented – unless you’re a .NET developer yourself, in which case you should have done this BEFORE your app ever got in front of a customer – but the capability is there. .NET applications have an XML “application configuration file”, which is usually named “(yourapp).exe.config”, in the same directory as (yourapp).exe. Inside that configuration file, there should already be a supportedRuntime directive, which targets a specific version of the .NET framework… but if there isn’t one, you can insert it like this:

 <!-- JRS : attempting to force use of .NET v2 SP2 -->
 <startup>
    <supportedRuntime version="v2.0.50727" />
 </startup>

Of course, one of the challenges is figuring out what the heck runtime version corresponds to a human-readable “version” of .NET – it is extremely specific, and if you don’t get the string right, your app will then refuse to run.  After some trial and error navigating MSDN, I finally found this kb article showing the correct version strings for the various versions of the framework that are out there.  Long story short, if you drop to a cmd prompt and dir %systemroot%\Microsoft.NET\Framework, you’ll get a list of the versions of the .NET framework installed on the machine in question, in the formats you need to fill in the supportedRuntime directive in an application configuration file like the example above. With all that figured out, the code snippet above did the trick – the offending application no longer tries to reference the latest version of .NET installed; now it sticks to 2.0 (and works!) even with 3.5 also installed on the server.