Microsoft Teams craptacular Machine-Wide Installer

I’m hoping someone might be able to help me with a problem I’ve facing…

About a year ago I deployed the Microsoft Teams Machine-Wide Installer (MSI) via the PSADT in the User context. The MSI was crap, and this was the only way to accomplish the installation properly. Teams is a user-based install and Microsoft hacked together a Machine-Wide installer which, as far as I know, just launches the MSI installer each time a new user logs in… It’s not ideal. Long story short, I forgot all about this and recently deployed an updated version of the MSI, but this time as System. And then the fun started…

My first mistake was marking the deployment as Required, because it then automatically ran on a couple dozen machines. Two entries for the Teams Machine-Wide Installer are now present in HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall. I assume there’s a MSI Code for the old install {DF8C4194-1791-41CC-A455-8EBCCF084366}, and one for the new install {731F6BAA-A986-45A4-8936-7C3AAAAA760B}. And for whatever reason, some machines are stuck in a loop where the Detection Logic for {731F6BAA-A986-45A4-8936-7C3AAAAA760B} just simply isn’t working even though it’s clearly valid.

So, I decided to purge the applicaiton in Configuration Manager and create a new one using PSADT to simply purge everything, re-install the Teams Machine-Wide Installer, and then reboot. Here’s the installation code I’m using:

	[string]$installPhase = 'Pre-Installation'
    Show-InstallationProgress -StatusMessage "Searching for previous Teams installations. Please wait..."
	$TeamsPath = [System.IO.Path]::Combine($env:LOCALAPPDATA, 'Microsoft', 'Teams')
	$TeamsUpdateExePath = [System.IO.Path]::Combine($env:LOCALAPPDATA, 'Microsoft', 'Teams', 'Update.exe')
	if (Test-Path -Path $TeamsUpdateExePath) {
		Show-InstallationProgress -StatusMessage "Uninstalling previous Teams installation. Please wait..."
		$proc = Start-Process -FilePath $TeamsUpdateExePath -ArgumentList "-uninstall -s" -PassThru
	if (Test-Path -Path $TeamsPath) {
		Show-InstallationProgress -StatusMessage "Cleaning previous Teams installation. Please wait..."
		Remove-Item –Path $TeamsPath -Recurse
    Start-Sleep -Seconds 10
	$Paths = Get-UserProfiles | Select-Object -ExpandProperty 'ProfilePath'
	foreach ($Path in $Paths)
		Remove-Folder -Path "$path\AppData\Local\Microsoft\Teams" -ContinueOnError $true
	Remove-MSIApplications -Name 'Teams Machine-Wide Installer'
    Remove-MSIApplications -Name 'Teams Machine-Wide Installer'
    Remove-MSIApplications -Name 'Microsoft Teams'
    Execute-MSI -Action 'Uninstall' -Path '{731F6BAA-A986-45A4-8936-7C3AAAAA760B}'
    Execute-MSI -Action 'Uninstall' -Path '{DF8C4194-1791-41CC-A455-8EBCCF084366}'
    Remove-Folder -Path "${env:ProgramFiles(x86)}\Teams Installer"

	[string]$installPhase = 'Installation'
	Show-InstallationProgress -StatusMessage "Installing Microsoft Teams. Please wait..."
	Execute-MSI -Action 'Install' -Path 'Teams_windows_x64.msi' -PassThru

As you can see, I’m trying numerous things to remove the installer… The problem is, the MSI files are not always removed. I’m guessing this is because Remove-MSIApplications is running as System, and the original MSI was installed as User? If that’s the case, is there a way to remove an MSI as User while keeping the Deployment Type running as System? Or maybe I could switch the DeploymentType to User, and then when the script reaches the Execute-MSI cmdlet I could run this as System? Is that even possible?

Any help would be greatly appreciated. Thank you so much.

To help someone else in this situation, using the Execute-ProcessAsUser allowed me to uninstall the MSI’s which were originally installed in the User context, but only if the same user was currently logged in… I have not been able to determine if there’s a method to uninstall an MSI across all users.

Execute-ProcessAsUser -Path "$($envWinDir)\System32\msiexec.exe" -Parameters "/x {731F6BAA-A986-45A4-8936-7C3AAAAA760B} /qn" -RunLevel HighestAvailable -Wait -PassThru
Execute-ProcessAsUser -Path "$($envWinDir)\System32\msiexec.exe" -Parameters "/x {DF8C4194-1791-41CC-A455-8EBCCF084366} /qn" -RunLevel HighestAvailable -Wait -PassThru