Last active
November 21, 2025 18:07
-
-
Save kamronbatman/466215e5d1324ade8abef925d1003905 to your computer and use it in GitHub Desktop.
Uninstall ConnectWise RMM / Continuum ITSPlatform & SAAZOD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # CW RMM Uninstaller Script | |
| # This script forcefully removes the ConnectWise RMM agent and its components. | |
| # Run with administrative privileges. | |
| $TranscriptPath = "$env:SystemDrive\CWRMM-Removal\CWRMM-Uninstall-$(Get-Date -Format yyyyMMdd-HHmmss).log" | |
| New-Item -Path $TranscriptPath -ItemType Directory -Force | Out-Null | |
| Start-Transcript -Path $TranscriptPath -Append | Out-Null | |
| Write-Output "" | |
| Write-Output "Beginning CW RMM Uninstall" | |
| # Uninstall ITSPlatform Official Method | |
| try { | |
| Write-Output "Stopping ITSPlatform Agent and Manager services..." | |
| $AgentCore = "C:\Program Files (x86)\ITSPlatform\agentcore\platform-agent-core.exe" | |
| $AgentMgr = "C:\Program Files (x86)\ITSPlatform\agentmanager\platform-agent-manager.exe" | |
| $CfgCore = "C:\Program Files (x86)\ITSPlatform\config\platform_agent_core_cfg.json" | |
| $LogCore = "C:\Program Files (x86)\ITSPlatform\log\platform_agent_core.log" | |
| $LogMgr = "C:\Program Files (x86)\ITSPlatform\log\platform_agent_manager.log" | |
| $SetupLogCore = "C:\Program Files (x86)\ITSPlatformSetupLogs\platform_agent_core.log" | |
| if (Test-Path $AgentCore) { | |
| Start-Process -FilePath $AgentCore -ArgumentList @($CfgCore, $LogCore, 'stopservice') -Wait -WindowStyle Hidden | |
| Write-Output "AgentCore stopservice invoked." | |
| } else { Write-Output "AgentCore executable not found, skipping stopservice." } | |
| if (Test-Path $AgentMgr) { | |
| Start-Process -FilePath $AgentMgr -ArgumentList @('stopservice', $LogMgr, $CfgCore) -Wait -WindowStyle Hidden | |
| Write-Output "AgentManager stopservice invoked." | |
| } else { Write-Output "AgentManager executable not found, skipping stopservice." } | |
| Write-Output "Disabling ITSPlatform Agent and Manager services..." | |
| if (Test-Path $AgentCore) { | |
| Start-Process -FilePath $AgentCore -ArgumentList @($CfgCore, $LogCore, 'disableservice') -Wait -WindowStyle Hidden | |
| Write-Output "AgentCore disableservice invoked." | |
| } | |
| if (Test-Path $AgentMgr) { | |
| Start-Process -FilePath $AgentMgr -ArgumentList @('disableservice', $LogMgr, $CfgCore) -Wait -WindowStyle Hidden | |
| Write-Output "AgentManager disableservice invoked." | |
| } | |
| Write-Output "Uninstalling ITSPlatform Agent (new RMM core)..." | |
| if (Test-Path $AgentCore) { | |
| Start-Process -FilePath $AgentCore -ArgumentList @($CfgCore, $SetupLogCore, 'uninstallagent') -Wait -WindowStyle Hidden | |
| Write-Output "AgentCore uninstallagent invoked." | |
| } else { | |
| Write-Output "AgentCore executable not found, skipping uninstallagent." | |
| } | |
| } | |
| catch { | |
| Write-Warning ("Official stop/disable/uninstall steps encountered an error: {0}" -f $_) | |
| } | |
| # Uninstall ITSPlatform Fallback Method | |
| Write-Output "Triggering ITSPlatform uninstall (WMI fallback)..." | |
| Get-WmiObject -Class Win32_Product -Filter "Name='ITSPlatform'" | ForEach-Object { $_.Uninstall() } | |
| # Run Uninstall.exe for SAAZOD | |
| Write-Output "Triggering SAAZOD uninstall..." | |
| if (Test-Path -Path "C:\Program Files (x86)\SAAZOD\Uninstall\Uninstall.exe") { | |
| Start-Process -FilePath "C:\Program Files (x86)\SAAZOD\Uninstall\Uninstall.exe" -Wait -ArgumentList '/silent /u:"C:\Program Files (x86)\SAAZOD\Uninstall\Uninstall.xml"' | |
| Start-Sleep -s 30 | |
| } | |
| else { | |
| Write-Output "INFO: SAAZOD uninstaller not found at C:\Program Files (x86)\SAAZOD\Uninstall\Uninstall.exe" | |
| } | |
| # Stop and force close related processes | |
| Write-Output "Stopping CW RMM processes..." | |
| $CWRMMProcesses = @( | |
| 'platform-agent*', | |
| 'platform-*-plugin', | |
| 'platform-communicator-tray', | |
| 'SAAZ*', | |
| 'rthlpdk' | |
| ) | |
| $ProcessesToStop = Get-Process -Name $CWRMMProcesses -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name | |
| forEach ($ProcessToStop in $ProcessesToStop) { | |
| if (Get-Process -Name "$ProcessToStop" -ErrorAction 'SilentlyContinue') { | |
| Write-Output "Stopping Process: $ProcessToStop" | |
| Get-Process -Name "$ProcessToStop" -ErrorAction 'SilentlyContinue' | Stop-Process -Force | |
| } | |
| } | |
| # Stop and force close related services | |
| Write-Output "Stopping CW RMM services..." | |
| $CWRMMServices = @( | |
| 'ITSPlatform*', | |
| 'SAAZ*' | |
| ) | |
| $ServicesToStop = Get-Service -Name $CWRMMServices -ErrorAction 'SilentlyContinue' | Select-Object -ExpandProperty Name | |
| forEach ($ServiceToStop in $ServicesToStop) { | |
| if (Get-Service -Name "$ServiceToStop" -ErrorAction 'SilentlyContinue') { | |
| Write-Output "Stopping Service: $ServiceToStop" | |
| Get-Service -Name "$ServiceToStop" -ErrorAction 'SilentlyContinue' | Stop-Service -Force | |
| } | |
| } | |
| # Delete specified services | |
| Write-Output "Deleting CW RMM services..." | |
| foreach ($service in $ServicesToStop) { | |
| Write-Output "Deleting service: $service" | |
| Start-Process -FilePath "sc.exe" -ArgumentList "delete", $service -NoNewWindow -Wait | |
| Start-Sleep -Seconds 1 | |
| } | |
| # Alternative service deletion method using CIM | |
| Get-CimInstance -ClassName win32_service | Where-Object { ($_.PathName -like '*ITSPlatform*') -or ($_.PathName -like '*SAAZ*') } | ForEach-Object { | |
| Write-Output "Attempting to remove service via CIM: $($_.Name)" | |
| Invoke-CimMethod $_ -Name StopService -ErrorAction SilentlyContinue | |
| Remove-CimInstance $_ -Verbose -Confirm:$false | |
| } | |
| # Delete the scheduled task | |
| Write-Output "Checking for and deleting scheduled task 'ITSPlatformSelfHealUtility'..." | |
| $taskName = "ITSPlatformSelfHealUtility" | |
| if (Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue) { | |
| Write-Output "Found and deleting scheduled task: $taskName" | |
| Unregister-ScheduledTask -TaskName $taskName -Confirm:$false | |
| Write-Output "Scheduled task '$taskName' has been deleted." | |
| } | |
| else { | |
| Write-Output "INFO: Scheduled task '$taskName' not found." | |
| } | |
| $CWRMMUninstallProcessesToStop = @( | |
| 'ITSPlatform*' | |
| ) | |
| $ProcessesToStop = Get-Process -Name $CWRMMUninstallProcessesToStop -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name | |
| forEach ($ProcessToStop in $ProcessesToStop) { | |
| if (Get-Process -Name "$ProcessToStop" -ErrorAction 'SilentlyContinue') { | |
| Write-Output "Stopping remaining process: $ProcessToStop" | |
| Get-Process -Name "$ProcessToStop" -ErrorAction 'SilentlyContinue' | Stop-Process -Force | |
| } | |
| } | |
| # Delete specified folders | |
| Write-Output "Deleting CW RMM related folders..." | |
| $FoldersToDelete = @( | |
| 'C:\Program Files (x86)\ITSPlatformSetupLogs', | |
| 'C:\Program Files (x86)\ITSPlatform', | |
| 'C:\Program Files (x86)\SAAZOD', | |
| 'C:\Program Files (x86)\SAAZODBKP', | |
| 'C:\ProgramData\SAAZOD' | |
| ) | |
| foreach ($folder in $FoldersToDelete) { | |
| if (Test-Path $folder) { | |
| Write-Output "Deleting folder: $folder" | |
| Remove-Item -Path $folder -Recurse -Force -Confirm:$false -Verbose | |
| } | |
| } | |
| # Remove "C:\Program" file, which can be created by faulty uninstallers | |
| Write-Output "Checking for rogue 'C:\Program' file..." | |
| if (Test-Path -LiteralPath "C:\Program" -PathType leaf) { | |
| Write-Output "Deleting rogue 'C:\Program' file." | |
| Remove-Item -LiteralPath "C:\Program" -Force -Confirm:$false -Verbose | |
| } | |
| # Remove registry keys | |
| Write-Output "Deleting CW RMM registry keys..." | |
| $RegistryKeysToRemove = @( | |
| 'HKLM:\SOFTWARE\WOW6432Node\SAAZOD', | |
| 'HKLM:\SOFTWARE\WOW6432Node\ITSPlatform' | |
| ) | |
| foreach ($RegistryKey in $RegistryKeysToRemove) { | |
| if (Test-Path -LiteralPath $RegistryKey) { | |
| Write-Output "Deleting registry key: $RegistryKey" | |
| Remove-Item -Path $RegistryKey -Recurse -Force -Confirm:$false -Verbose | |
| } | |
| } | |
| # Remove the registry key with leading spaces | |
| $BlankRegistryKey = "HKLM:\SOFTWARE\WOW6432Node\ \ITSPlatform" | |
| if (Test-Path -LiteralPath $BlankRegistryKey) { | |
| Write-Output "Deleting blank-padded registry key: $BlankRegistryKey" | |
| try { | |
| Remove-Item -Path $BlankRegistryKey -Recurse -Force -Confirm:$false -Verbose -ErrorAction Stop | |
| Write-Output "Blank-padded registry key deleted successfully." | |
| } | |
| catch { | |
| Write-Output "ERROR: Failed to delete blank-padded registry key: $_" | |
| } | |
| } | |
| ### Clean up installer registry keys | |
| Write-Output "Cleaning up installer registry keys for ITSPlatform..." | |
| $startPath = 'HKLM:\SOFTWARE\Classes\Installer\Products\' | |
| $targetProductName = 'ITSPlatform' | |
| try { | |
| $ProductRegistryKeysToRemove = Get-ChildItem -Path $startPath -Recurse -ErrorAction SilentlyContinue | ForEach-Object { | |
| if ((Get-ItemProperty -Path $_.PSPath -Name 'ProductName' -ErrorAction SilentlyContinue).ProductName -eq $targetProductName) { | |
| $_.PSPath | |
| } | |
| } | |
| if ($ProductRegistryKeysToRemove) { | |
| foreach ($keyPath in $ProductRegistryKeysToRemove) { | |
| if (Test-Path -LiteralPath $keyPath) { | |
| Write-Output "Deleting installer registry key: $keyPath" | |
| Remove-Item -Path $keyPath -Recurse -Force -Confirm:$false -Verbose | |
| } | |
| } | |
| } else { | |
| Write-Output "INFO: No matching installer registry keys found for '$targetProductName'." | |
| } | |
| } catch { | |
| Write-Output "WARNING: Could not complete installer registry key cleanup. Error: $_" | |
| } | |
| Write-Output "" | |
| Write-Output "Done! CW RMM should be successfully uninstalled and remnants removed." | |
| Stop-Transcript |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment