refactor(scripts): optimize system remediation and M365 export scripts
- teams: harden Classic Teams removal, protect New Teams, and clean HKU run keys - dotnet: add bootstrapper EXE uninstall support and remove orphaned 3.1.* folders - teams: add MSIX package targeting and version parsing for vulnerable New Teams builds - m365: improve Graph SDK export speed, reuse sessions, and add null-safe handling
This commit is contained in:
1 parent
4fd95b76d6
commit
5ef82842f2
19 files changed
+1651
-1268
No files matched your search
@@ -0,0 +1,193 @@
|
||||
#Requires -RunAsAdministrator
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Removes specific vulnerable/outdated versions of Classic Teams and New Teams (MSTeams).
|
||||
.DESCRIPTION
|
||||
Checks for targeted build numbers across Classic Teams (Machine-Wide Installer, user AppData)
|
||||
and New Teams (MSIX AppX provisioned and per-user packages), cleanly uninstalling only
|
||||
the matching versions while leaving compliant versions untouched.
|
||||
#>
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
Write-Host "Starting targeted Microsoft Teams cleanup..." -ForegroundColor Cyan
|
||||
|
||||
# Targeted vulnerable versions (includes Classic Teams 1.x and New Teams 23x/24x/25x builds)
|
||||
$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"
|
||||
)
|
||||
|
||||
# Helper function for version string normalization & comparison
|
||||
function Test-IsTargetVersion {
|
||||
param (
|
||||
[string]$VersionString,
|
||||
[string[]]$TargetList
|
||||
)
|
||||
if ([string]::IsNullOrWhiteSpace($VersionString)) { return$false }
|
||||
|
||||
$cleanVersion =$VersionString.Trim()
|
||||
if ($TargetList -contains $cleanVersion) { return$true }
|
||||
|
||||
try {
|
||||
$parsedVersion = [version]$cleanVersion
|
||||
foreach ($target in$TargetList) {
|
||||
try {
|
||||
if ([version]$target -eq $parsedVersion) { return$true }
|
||||
} catch {}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
# 1. Safely stop targeted processes
|
||||
Write-Host "Checking for running processes..." -ForegroundColor Cyan
|
||||
Get-Process -Name "Teams" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
||||
Get-Process -Name "Update" -ErrorAction SilentlyContinue | Where-Object {
|
||||
$_.Path -like "*\Microsoft\Teams\Update.exe"
|
||||
} | Stop-Process -Force -ErrorAction SilentlyContinue
|
||||
|
||||
# Stop ms-teams ONLY if the running executable belongs to a target version
|
||||
Get-Process -Name "ms-teams" -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
$procVersion =$_.MainModule.FileVersionInfo.FileVersion
|
||||
if (Test-IsTargetVersion -VersionString $procVersion -TargetList$TargetVersions) {
|
||||
Write-Host "Stopping New Teams process (running vulnerable version $procVersion)..." -ForegroundColor Yellow
|
||||
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
# 2. Remediate targeted Teams Machine-Wide Installer (HKLM)
|
||||
Write-Host "`nScanning Teams Machine-Wide Installer..." -ForegroundColor Cyan
|
||||
$UninstallRegistryPaths = @(
|
||||
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
|
||||
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
|
||||
)
|
||||
|
||||
foreach ($path in $UninstallRegistryPaths) {
|
||||
Get-ItemProperty $path -ErrorAction SilentlyContinue | Where-Object {
|
||||
$_.DisplayName -eq "Teams Machine-Wide Installer" -and
|
||||
(Test-IsTargetVersion -VersionString $_.DisplayVersion -TargetList $TargetVersions)
|
||||
} | ForEach-Object {
|
||||
Write-Host "Found targeted Machine-Wide Installer version: $($_.DisplayVersion)" -ForegroundColor Yellow
|
||||
|
||||
if ($_.UninstallString -match "\{[A-Fa-f0-9\-]{36}\}") {
|
||||
$productCode = $Matches[0]
|
||||
Start-Process -FilePath "msiexec.exe" -ArgumentList "/x $productCode /qn /norestart" -Wait -NoNewWindow
|
||||
} elseif ($_.UninstallString) {
|
||||
Start-Process -FilePath "cmd.exe" -ArgumentList "/c `"$($_.UninstallString)`" /quiet /norestart" -Wait -NoNewWindow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 3. Remediate targeted Classic Teams (User Profiles)
|
||||
Write-Host "`nScanning user profiles for Classic Teams..." -ForegroundColor Cyan
|
||||
$usersRoot = Join-Path$env:SystemDrive "Users"
|
||||
$userProfiles = Get-ChildItem -Path $usersRoot -Directory -ErrorAction SilentlyContinue \vert{} Where-Object {$_.Name -notin @("Public", "Default", "Default User", "All Users", "defaultuser0")
|
||||
}
|
||||
|
||||
foreach ($profile in$userProfiles) {
|
||||
$localTeamsFolder = Join-Path$profile.FullName "AppData\Local\Microsoft\Teams"
|
||||
$roamingTeamsFolder = Join-Path$profile.FullName "AppData\Roaming\Microsoft\Teams"
|
||||
$currentExe = Join-Path$localTeamsFolder "current\Teams.exe"
|
||||
$updateExe = Join-Path$localTeamsFolder "Update.exe"
|
||||
|
||||
if (Test-Path $localTeamsFolder) {
|
||||
$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 (Test-IsTargetVersion -VersionString $detectedVersion -TargetList$TargetVersions) {
|
||||
Write-Host "Removing Classic Teams ($detectedVersion) for profile: $($profile.Name)" -ForegroundColor Yellow
|
||||
|
||||
if (Test-Path $updateExe) {
|
||||
Start-Process -FilePath $updateExe -ArgumentList "--uninstall -s" -Wait -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
Remove-Item -Path $localTeamsFolder -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path $roamingTeamsFolder -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 4. Remediate targeted New Teams (AppX / MSIX Packages)
|
||||
Write-Host "`nScanning New Teams (MSTeams) MSIX packages..." -ForegroundColor Cyan
|
||||
|
||||
# Remove provisioned package if version matches
|
||||
Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue | Where-Object {
|
||||
$_.DisplayName -eq "MSTeams" -and (Test-IsTargetVersion -VersionString $_.Version -TargetList $TargetVersions)
|
||||
} | ForEach-Object {
|
||||
Write-Host "Removing targeted provisioned MSTeams package version: $($_.Version)" -ForegroundColor Yellow
|
||||
Remove-AppxProvisionedPackage -Online -PackageName $_.PackageName -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# Remove per-user AppX packages if version matches
|
||||
Get-AppxPackage -Name "MSTeams" -AllUsers -ErrorAction SilentlyContinue | Where-Object {
|
||||
Test-IsTargetVersion -VersionString $_.Version -TargetList $TargetVersions
|
||||
} | ForEach-Object {
|
||||
Write-Host "Removing targeted MSTeams AppX package version: $($_.Version) for all users" -ForegroundColor Yellow
|
||||
Remove-AppxPackage -Package $_.PackageFullName -AllUsers -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# 5. Clean Startup Run Keys across loaded user hives
|
||||
$hkuPath = "Registry::HKEY_USERS"
|
||||
Get-ChildItem -Path $hkuPath -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
$runKey = Join-Path $_.PSPath "Software\Microsoft\Windows\CurrentVersion\Run"
|
||||
if (Test-Path $runKey) {
|
||||
$val = Get-ItemProperty -Path $runKey -Name "com.squirrel.teams.teams" -ErrorAction SilentlyContinue
|
||||
if ($val) {
|
||||
Remove-ItemProperty -Path $runKey -Name "com.squirrel.teams.teams" -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 6. Final Verification
|
||||
Write-Host "`nPerforming final verification..." -ForegroundColor Cyan
|
||||
|
||||
$remainingMachineWide = foreach ($path in$UninstallRegistryPaths) {
|
||||
Get-ItemProperty $path -ErrorAction SilentlyContinue \vert{} Where-Object {$_.DisplayName -eq "Teams Machine-Wide Installer" -and
|
||||
(Test-IsTargetVersion -VersionString $_.DisplayVersion -TargetList$TargetVersions)
|
||||
}
|
||||
}
|
||||
|
||||
$remainingClassicFolders = foreach ($profile in$userProfiles) {
|
||||
$exe = Join-Path$profile.FullName "AppData\Local\Microsoft\Teams\current\Teams.exe"
|
||||
if (Test-Path $exe) {
|
||||
$ver = (Get-Item$exe).VersionInfo.FileVersion
|
||||
if (Test-IsTargetVersion -VersionString $ver -TargetList $TargetVersions) {$exe }
|
||||
}
|
||||
}
|
||||
|
||||
$remainingNewTeams = Get-AppxPackage -Name "MSTeams" -AllUsers -ErrorAction SilentlyContinue | Where-Object {
|
||||
Test-IsTargetVersion -VersionString $_.Version -TargetList$TargetVersions
|
||||
}
|
||||
|
||||
if ($remainingMachineWide -or $remainingClassicFolders -or$remainingNewTeams) {
|
||||
Write-Host "ERROR: Some targeted Teams versions still remain on the endpoint." -ForegroundColor Red
|
||||
exit 1
|
||||
} else {
|
||||
Write-Host "Targeted Teams remediation completed successfully." -ForegroundColor Green
|
||||
|
||||
# Display active/healthy New Teams version if installed
|
||||
$healthyTeams = Get-AppxPackage -Name "MSTeams" -AllUsers -ErrorAction SilentlyContinue
|
||||
if ($healthyTeams) {
|
||||
Write-Host "Active, non-vulnerable New Teams installation detected:" -ForegroundColor Green
|
||||
$healthyTeams | Select-Object Name, Version, PackageFullName | Format-Table -AutoSize | Out-String | Write-Host
|
||||
}
|
||||
exit 0
|
||||
}
|
||||
Reference in new issue
Block a user