233 lines
7.5 KiB
PowerShell
233 lines
7.5 KiB
PowerShell
# Remove-SpecificTeamsVersions.ps1
|
|
# Removes specified vulnerable/old versions of classic Microsoft Teams and Teams Machine-Wide Installer.
|
|
# Leaves new Teams / MSTeams MSIX app installed.
|
|
|
|
$ErrorActionPreference = "Continue"
|
|
|
|
Write-Output "Starting targeted Microsoft Teams cleanup..."
|
|
|
|
# Versions to remove
|
|
$TargetVersions = @(
|
|
"24334.1103.3302.5694",
|
|
"25045.406.3471.2143",
|
|
"24124.2402.2858.5617",
|
|
"24004.1403.2634.2418",
|
|
"23195.1506.2253.6778",
|
|
"24277.3102.3183.2670",
|
|
"24256.2502.3123.1",
|
|
"24165.1306.2986.9504",
|
|
"25031.702.3408.1909",
|
|
"24244.507.3118.4732",
|
|
"23119.303.2080.2726",
|
|
"1.7.0.7956",
|
|
"25044.2208.3471.2155",
|
|
"24348.802.3311.5092",
|
|
"23335.242.2641.4129"
|
|
)
|
|
|
|
# Stop Teams-related processes
|
|
$ProcessNames = @(
|
|
"Teams",
|
|
"ms-teams",
|
|
"msteams",
|
|
"Microsoft.Teams",
|
|
"Update"
|
|
)
|
|
|
|
foreach ($ProcessName in $ProcessNames) {
|
|
Get-Process -Name $ProcessName -ErrorAction SilentlyContinue |
|
|
Stop-Process -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
Start-Sleep -Seconds 5
|
|
|
|
# Registry uninstall locations
|
|
$UninstallRegistryPaths = @(
|
|
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
|
|
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
|
|
)
|
|
|
|
# Remove matching Teams Machine-Wide Installer versions
|
|
Write-Output "Checking for targeted Teams Machine-Wide Installer versions..."
|
|
|
|
$MachineWideInstallers = foreach ($Path in $UninstallRegistryPaths) {
|
|
Get-ItemProperty $Path -ErrorAction SilentlyContinue | Where-Object {
|
|
$_.DisplayName -eq "Teams Machine-Wide Installer" -and
|
|
$TargetVersions -contains $_.DisplayVersion
|
|
}
|
|
}
|
|
|
|
foreach ($App in $MachineWideInstallers) {
|
|
Write-Output "Found targeted Teams Machine-Wide Installer: $($App.DisplayVersion)"
|
|
|
|
if ($App.UninstallString -match "\{[A-Fa-f0-9\-]{36}\}") {
|
|
$ProductCode = $Matches[0]
|
|
Write-Output "Removing Teams Machine-Wide Installer using MSI product code: $ProductCode"
|
|
|
|
Start-Process -FilePath "msiexec.exe" `
|
|
-ArgumentList "/x $ProductCode /qn /norestart" `
|
|
-Wait
|
|
}
|
|
elseif ($App.UninstallString) {
|
|
Write-Output "Removing Teams Machine-Wide Installer using uninstall string."
|
|
|
|
Start-Process -FilePath "cmd.exe" `
|
|
-ArgumentList "/c $($App.UninstallString) /quiet /norestart" `
|
|
-Wait
|
|
}
|
|
else {
|
|
Write-Output "No uninstall string found for Teams Machine-Wide Installer version $($App.DisplayVersion)."
|
|
}
|
|
}
|
|
|
|
# Remove matching classic Teams per-user installs
|
|
Write-Output "Checking user profiles for targeted classic Teams versions..."
|
|
|
|
$UserProfiles = Get-ChildItem "C:\Users" -Directory -ErrorAction SilentlyContinue | Where-Object {
|
|
$_.Name -notin @(
|
|
"Public",
|
|
"Default",
|
|
"Default User",
|
|
"All Users",
|
|
"defaultuser0"
|
|
)
|
|
}
|
|
|
|
foreach ($Profile in $UserProfiles) {
|
|
$TeamsFolder = Join-Path $Profile.FullName "AppData\Local\Microsoft\Teams"
|
|
$UpdateExe = Join-Path $TeamsFolder "Update.exe"
|
|
$CurrentExe = Join-Path $TeamsFolder "current\Teams.exe"
|
|
|
|
if (-not (Test-Path $TeamsFolder)) {
|
|
continue
|
|
}
|
|
|
|
$DetectedVersion = $null
|
|
|
|
if (Test-Path $CurrentExe) {
|
|
$DetectedVersion = (Get-Item $CurrentExe).VersionInfo.FileVersion
|
|
}
|
|
|
|
if (-not $DetectedVersion -and (Test-Path $UpdateExe)) {
|
|
$DetectedVersion = (Get-Item $UpdateExe).VersionInfo.FileVersion
|
|
}
|
|
|
|
if ($TargetVersions -contains $DetectedVersion) {
|
|
Write-Output "Found targeted classic Teams version $DetectedVersion in profile: $($Profile.Name)"
|
|
|
|
if (Test-Path $UpdateExe) {
|
|
Write-Output "Attempting silent uninstall for profile: $($Profile.Name)"
|
|
Start-Process -FilePath $UpdateExe `
|
|
-ArgumentList "--uninstall -s" `
|
|
-Wait `
|
|
-ErrorAction SilentlyContinue
|
|
|
|
Start-Sleep -Seconds 3
|
|
}
|
|
|
|
if (Test-Path $TeamsFolder) {
|
|
Write-Output "Removing remaining classic Teams folder for profile: $($Profile.Name)"
|
|
Remove-Item -Path $TeamsFolder -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
else {
|
|
Write-Output "Skipping profile $($Profile.Name). Classic Teams version '$DetectedVersion' is not in target list."
|
|
}
|
|
}
|
|
|
|
# Check HKCU-style per-user uninstall entries under user registry hives if loaded
|
|
Write-Output "Checking loaded user registry hives for targeted classic Teams uninstall entries..."
|
|
|
|
$LoadedUserUninstallPaths = Get-ChildItem "Registry::HKEY_USERS" -ErrorAction SilentlyContinue | ForEach-Object {
|
|
"Registry::$($_.Name)\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
|
|
}
|
|
|
|
foreach ($Path in $LoadedUserUninstallPaths) {
|
|
$UserTeamsApps = Get-ItemProperty $Path -ErrorAction SilentlyContinue | Where-Object {
|
|
(
|
|
$_.DisplayName -eq "Microsoft Teams" -or
|
|
$_.DisplayName -eq "MicrosoftTeams"
|
|
) -and
|
|
$TargetVersions -contains $_.DisplayVersion
|
|
}
|
|
|
|
foreach ($App in $UserTeamsApps) {
|
|
Write-Output "Found targeted per-user Teams uninstall entry: $($App.DisplayName) $($App.DisplayVersion)"
|
|
|
|
if ($App.UninstallString) {
|
|
Start-Process -FilePath "cmd.exe" `
|
|
-ArgumentList "/c $($App.UninstallString) --uninstall -s" `
|
|
-Wait `
|
|
-ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
}
|
|
|
|
# Verify new Teams remains installed
|
|
Write-Output "Checking for new Teams / MSTeams..."
|
|
|
|
$NewTeams = Get-AppxPackage -AllUsers -ErrorAction SilentlyContinue | Where-Object {
|
|
$_.Name -eq "MSTeams"
|
|
}
|
|
|
|
if ($NewTeams) {
|
|
Write-Output "New Teams / MSTeams is installed and was left in place:"
|
|
$NewTeams | Select-Object Name, Version, PackageFullName | Format-List | Out-String | Write-Output
|
|
}
|
|
else {
|
|
Write-Output "WARNING: New Teams / MSTeams was not detected."
|
|
}
|
|
|
|
# Final verification
|
|
Write-Output "Performing final verification..."
|
|
|
|
$RemainingMachineWide = foreach ($Path in $UninstallRegistryPaths) {
|
|
Get-ItemProperty $Path -ErrorAction SilentlyContinue | Where-Object {
|
|
$_.DisplayName -eq "Teams Machine-Wide Installer" -and
|
|
$TargetVersions -contains $_.DisplayVersion
|
|
}
|
|
}
|
|
|
|
$RemainingClassicTeamsFolders = foreach ($Profile in $UserProfiles) {
|
|
$TeamsFolder = Join-Path $Profile.FullName "AppData\Local\Microsoft\Teams"
|
|
$CurrentExe = Join-Path $TeamsFolder "current\Teams.exe"
|
|
|
|
if (Test-Path $CurrentExe) {
|
|
$Version = (Get-Item $CurrentExe).VersionInfo.FileVersion
|
|
|
|
if ($TargetVersions -contains $Version) {
|
|
[PSCustomObject]@{
|
|
Profile = $Profile.Name
|
|
Version = $Version
|
|
Path = $TeamsFolder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($RemainingMachineWide -or $RemainingClassicTeamsFolders) {
|
|
Write-Output "Targeted Teams cleanup completed, but some targeted versions may still remain."
|
|
|
|
if ($RemainingMachineWide) {
|
|
Write-Output "Remaining Teams Machine-Wide Installer entries:"
|
|
$RemainingMachineWide |
|
|
Select-Object DisplayName, DisplayVersion, UninstallString |
|
|
Format-Table -AutoSize |
|
|
Out-String |
|
|
Write-Output
|
|
}
|
|
|
|
if ($RemainingClassicTeamsFolders) {
|
|
Write-Output "Remaining classic Teams folders:"
|
|
$RemainingClassicTeamsFolders |
|
|
Format-Table -AutoSize |
|
|
Out-String |
|
|
Write-Output
|
|
}
|
|
|
|
exit 1
|
|
}
|
|
else {
|
|
Write-Output "Targeted Teams versions were successfully removed or were not present."
|
|
exit 0
|
|
} |