MVP - Most Valuable Professional
rss

Just can't get enough of IT

This blog is about mostly anything in IT. But the primary focuses are Microsoft technologies like Exchange Server, Microsoft 365, Microsoft Teams, and Cloud Security.

Exchange Server 2016 LogoRecently I had to support the uninstall of Exchange Server 2016 CU10 on a Windows Server 2019 system. That this setup is not supported is a different topic. In this case, a new Exchange Server 2016 system was placed in service, and the old system needed to be removed from the on-premises Exchange organization.

We mounted the Exchange 2016 CU10 ISO, and ran the following command from an administrative command line:

Setup.exe /mode:uninstall

 

Prerequisites Checks

The prerequisites check failed with an odd error:

http://terenceluk.blogspot.com/2017/01/attempting-to-delete-exchange-server.html

Querying for any incompleted public folder migration requests returned no results. But the prerequisites check insisted that there was an existing public folder migration request. In such a case you already know that you have to use ADSIEdit to find the object in question. 

It turned out that the prerequisites check was right, as we found a single public folder migration request in the Active Directory configuration partition. The request was an artifact of an unsuccessful migration attempt in 2019. After we have checked that the current modern public folder hierarchy worked as expected, we deleted the artifact from Active Directory.

Now the uninstall procedure passed the prerequisites check successfully and the uninstaller moved on removed Exchange Server 2016 step by step.

Until...

 

Uninstall Error

The uninstall step Language Files an Access Denied exception while executing MSIEXEC uninstall actions for each Language Pack.

Language Files                                                                                    FAILED

The following error was generated when "$error.Clear();
$regPath='HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';
$PackageGUIDRegEx = "{DEDFFB[0-9a-fA-F]{2}-42EC-4E26-[0-9a-fA-F]{4}-430E86DF378C}";
$InstallPath = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v15\setup').MsiInstallPath;

if(test-path ($regPath))
{
Write-ExchangeSetupLog -info ("Removing " +  $RoleLanguagePackType + " Language Packs.");
Get-ChildItem ($regPath) | foreach{
if($_ -match "(?<ProductCode>$PackageGUIDRegEx)") {
$langPackPackageCode = $matches['ProductCode'];
if($langPackPackageCode -ne $null -and $langPackPackageCode.Length -ne 0) {
Write-ExchangeSetupLog -info ("Removing package $langPackPackageCode");
$language = $langPackPackageCode.Substring(20,4);
$logFilePath = [IO.Path]::Combine($RoleLogFilePath,"Uninstall") + '.' + $language +
'.' + "Client" + "." + $RoleLogDateTime + ".msilog";
uninstall-MsiPackage -ProductCode ($langPackPackageCode) -LogFile ($logFilePath);
};
};
};
Get-Childitem -Path $InstallPath -include ".Localized.js",".Localized.min.js" -recurse | foreach ($) {remove-item $.fullname};
Write-ExchangeSetupLog -info "Remove Language Packs completed.";
};
" was run: "**System.UnauthorizedAccessException: Access is denied** ---> System.ComponentModel.Win32Exception: Access is denied
--- End of inner exception stack trace ---
at System.Management.Automation.Utils.NativeDirectoryExists(String path)
at System.Management.Automation.SessionStateInternal.IsItemContainer(CmdletProvider providerInstance, String path, CmdletProviderContext context)".

 

Interestingly, the ExchangeSetup log file showed that the uninstaller wrote the informational text Remove Language Packs completed successfully. 

 

Solution

After following an idea to remove the language pack-related registry keys and other fancy approaches, we did something trivial. We restarted the server, mounted the ISO file, and ran Setup.exe /mode:uninstall again. 

The uninstaller process now passed the step Language Files without any issues.

I sometimes like simple solutions.

 

Enjoy Exchange Server. 

 

 

Read More »