Synced files: - Complete claude-projects import (5 catalog files) - Client directory with 12 clients - Project directory with 12 projects - Credentials updated (100+ sets) - Session logs consolidated - Agent coordination rules updated - Task management integration Major work completed: - Exhaustive cataloging of claude-projects - All session logs analyzed (38 files) - All credentials extracted and organized - Client infrastructure documented - Problem solutions cataloged (70+) Machine: ACG-M-L5090 Timestamp: 2026-01-26 16:45:54 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
287 lines
9.0 KiB
PowerShell
287 lines
9.0 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Removes CentraStage/Datto RMM agent from Windows machines.
|
|
|
|
.DESCRIPTION
|
|
This script safely uninstalls the CentraStage/Datto RMM agent by:
|
|
- Stopping all CentraStage services
|
|
- Running the uninstaller
|
|
- Cleaning up residual files and registry entries
|
|
- Removing scheduled tasks
|
|
|
|
.PARAMETER Force
|
|
Skip confirmation prompts
|
|
|
|
.EXAMPLE
|
|
.\Remove-CentraStage.ps1
|
|
Removes CentraStage with confirmation prompts
|
|
|
|
.EXAMPLE
|
|
.\Remove-CentraStage.ps1 -Force
|
|
Removes CentraStage without confirmation
|
|
|
|
.NOTES
|
|
Author: ClaudeTools
|
|
Requires: Administrator privileges
|
|
Last Updated: 2026-01-23
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[switch]$Force
|
|
)
|
|
|
|
#Requires -RunAsAdministrator
|
|
|
|
# ASCII markers only - no emojis
|
|
function Write-Status {
|
|
param(
|
|
[string]$Message,
|
|
[ValidateSet('INFO', 'SUCCESS', 'WARNING', 'ERROR')]
|
|
[string]$Level = 'INFO'
|
|
)
|
|
|
|
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
|
|
$color = switch ($Level) {
|
|
'INFO' { 'Cyan' }
|
|
'SUCCESS' { 'Green' }
|
|
'WARNING' { 'Yellow' }
|
|
'ERROR' { 'Red' }
|
|
}
|
|
|
|
Write-Host "[$timestamp] [$Level] $Message" -ForegroundColor $color
|
|
}
|
|
|
|
# Check if running as administrator
|
|
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
Write-Status "This script must be run as Administrator" -Level ERROR
|
|
exit 1
|
|
}
|
|
|
|
Write-Status "Starting CentraStage/Datto RMM removal process" -Level INFO
|
|
|
|
# Confirmation prompt
|
|
if (-not $Force) {
|
|
$confirm = Read-Host "This will remove CentraStage/Datto RMM from this machine. Continue? (Y/N)"
|
|
if ($confirm -ne 'Y' -and $confirm -ne 'y') {
|
|
Write-Status "Operation cancelled by user" -Level WARNING
|
|
exit 0
|
|
}
|
|
}
|
|
|
|
# Define CentraStage service names
|
|
$services = @(
|
|
'CagService',
|
|
'CentraStage',
|
|
'CagService*',
|
|
'Datto RMM'
|
|
)
|
|
|
|
# Define installation paths
|
|
$installPaths = @(
|
|
"${env:ProgramFiles}\CentraStage",
|
|
"${env:ProgramFiles(x86)}\CentraStage",
|
|
"${env:ProgramFiles}\SYSTEMMONITOR",
|
|
"${env:ProgramFiles(x86)}\SYSTEMMONITOR"
|
|
)
|
|
|
|
# Define registry paths
|
|
$registryPaths = @(
|
|
'HKLM:\SOFTWARE\CentraStage',
|
|
'HKLM:\SOFTWARE\WOW6432Node\CentraStage',
|
|
'HKLM:\SYSTEM\CurrentControlSet\Services\CagService',
|
|
'HKLM:\SYSTEM\CurrentControlSet\Services\CentraStage'
|
|
)
|
|
|
|
# Stop all CentraStage services
|
|
Write-Status "Stopping CentraStage services..." -Level INFO
|
|
foreach ($serviceName in $services) {
|
|
try {
|
|
$matchingServices = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
|
|
foreach ($service in $matchingServices) {
|
|
if ($service.Status -eq 'Running') {
|
|
Write-Status "Stopping service: $($service.Name)" -Level INFO
|
|
Stop-Service -Name $service.Name -Force -ErrorAction Stop
|
|
Write-Status "Service stopped: $($service.Name)" -Level SUCCESS
|
|
}
|
|
}
|
|
}
|
|
catch {
|
|
Write-Status "Could not stop service $serviceName: $_" -Level WARNING
|
|
}
|
|
}
|
|
|
|
# Find and run uninstaller
|
|
Write-Status "Looking for CentraStage uninstaller..." -Level INFO
|
|
$uninstallers = @()
|
|
|
|
# Check registry for uninstaller
|
|
$uninstallKeys = @(
|
|
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
|
|
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
|
)
|
|
|
|
foreach ($key in $uninstallKeys) {
|
|
Get-ItemProperty $key -ErrorAction SilentlyContinue | Where-Object {
|
|
$_.DisplayName -like '*CentraStage*' -or
|
|
$_.DisplayName -like '*Datto RMM*'
|
|
} | ForEach-Object {
|
|
if ($_.UninstallString) {
|
|
$uninstallers += $_.UninstallString
|
|
Write-Status "Found uninstaller: $($_.DisplayName)" -Level INFO
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check common installation paths for uninstaller
|
|
foreach ($path in $installPaths) {
|
|
$uninstallExe = Join-Path $path "uninstall.exe"
|
|
if (Test-Path $uninstallExe) {
|
|
$uninstallers += $uninstallExe
|
|
Write-Status "Found uninstaller at: $uninstallExe" -Level INFO
|
|
}
|
|
}
|
|
|
|
# Run uninstallers
|
|
if ($uninstallers.Count -gt 0) {
|
|
foreach ($uninstaller in $uninstallers) {
|
|
try {
|
|
Write-Status "Running uninstaller: $uninstaller" -Level INFO
|
|
|
|
# Parse uninstall string
|
|
if ($uninstaller -match '^"([^"]+)"(.*)$') {
|
|
$exe = $matches[1]
|
|
$args = $matches[2].Trim()
|
|
}
|
|
else {
|
|
$exe = $uninstaller
|
|
$args = ""
|
|
}
|
|
|
|
# Add silent parameters
|
|
$silentArgs = "/S /VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
|
|
if ($args) {
|
|
$args = "$args $silentArgs"
|
|
}
|
|
else {
|
|
$args = $silentArgs
|
|
}
|
|
|
|
$process = Start-Process -FilePath $exe -ArgumentList $args -Wait -PassThru -NoNewWindow
|
|
|
|
if ($process.ExitCode -eq 0) {
|
|
Write-Status "Uninstaller completed successfully" -Level SUCCESS
|
|
}
|
|
else {
|
|
Write-Status "Uninstaller exited with code: $($process.ExitCode)" -Level WARNING
|
|
}
|
|
}
|
|
catch {
|
|
Write-Status "Error running uninstaller: $_" -Level ERROR
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
Write-Status "No uninstaller found in registry or standard paths" -Level WARNING
|
|
}
|
|
|
|
# Remove services
|
|
Write-Status "Removing CentraStage services..." -Level INFO
|
|
foreach ($serviceName in $services) {
|
|
try {
|
|
$matchingServices = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
|
|
foreach ($service in $matchingServices) {
|
|
Write-Status "Removing service: $($service.Name)" -Level INFO
|
|
sc.exe delete $service.Name | Out-Null
|
|
Write-Status "Service removed: $($service.Name)" -Level SUCCESS
|
|
}
|
|
}
|
|
catch {
|
|
Write-Status "Could not remove service $serviceName: $_" -Level WARNING
|
|
}
|
|
}
|
|
|
|
# Remove installation directories
|
|
Write-Status "Removing installation directories..." -Level INFO
|
|
foreach ($path in $installPaths) {
|
|
if (Test-Path $path) {
|
|
try {
|
|
Write-Status "Removing directory: $path" -Level INFO
|
|
Remove-Item -Path $path -Recurse -Force -ErrorAction Stop
|
|
Write-Status "Directory removed: $path" -Level SUCCESS
|
|
}
|
|
catch {
|
|
Write-Status "Could not remove directory $path: $_" -Level WARNING
|
|
}
|
|
}
|
|
}
|
|
|
|
# Remove registry entries
|
|
Write-Status "Removing registry entries..." -Level INFO
|
|
foreach ($regPath in $registryPaths) {
|
|
if (Test-Path $regPath) {
|
|
try {
|
|
Write-Status "Removing registry key: $regPath" -Level INFO
|
|
Remove-Item -Path $regPath -Recurse -Force -ErrorAction Stop
|
|
Write-Status "Registry key removed: $regPath" -Level SUCCESS
|
|
}
|
|
catch {
|
|
Write-Status "Could not remove registry key $regPath: $_" -Level WARNING
|
|
}
|
|
}
|
|
}
|
|
|
|
# Remove scheduled tasks
|
|
Write-Status "Removing CentraStage scheduled tasks..." -Level INFO
|
|
try {
|
|
$tasks = Get-ScheduledTask -TaskPath '\' -ErrorAction SilentlyContinue | Where-Object {
|
|
$_.TaskName -like '*CentraStage*' -or
|
|
$_.TaskName -like '*Datto*' -or
|
|
$_.TaskName -like '*Cag*'
|
|
}
|
|
|
|
foreach ($task in $tasks) {
|
|
Write-Status "Removing scheduled task: $($task.TaskName)" -Level INFO
|
|
Unregister-ScheduledTask -TaskName $task.TaskName -Confirm:$false -ErrorAction Stop
|
|
Write-Status "Scheduled task removed: $($task.TaskName)" -Level SUCCESS
|
|
}
|
|
}
|
|
catch {
|
|
Write-Status "Error removing scheduled tasks: $_" -Level WARNING
|
|
}
|
|
|
|
# Final verification
|
|
Write-Status "Verifying removal..." -Level INFO
|
|
|
|
$remainingServices = Get-Service -Name 'Cag*','*CentraStage*','*Datto*' -ErrorAction SilentlyContinue
|
|
$remainingPaths = $installPaths | Where-Object { Test-Path $_ }
|
|
$remainingRegistry = $registryPaths | Where-Object { Test-Path $_ }
|
|
|
|
if ($remainingServices.Count -eq 0 -and $remainingPaths.Count -eq 0 -and $remainingRegistry.Count -eq 0) {
|
|
Write-Status "CentraStage/Datto RMM successfully removed!" -Level SUCCESS
|
|
Write-Status "A system restart is recommended" -Level INFO
|
|
}
|
|
else {
|
|
Write-Status "Removal completed with warnings:" -Level WARNING
|
|
if ($remainingServices.Count -gt 0) {
|
|
Write-Status " - $($remainingServices.Count) service(s) still present" -Level WARNING
|
|
}
|
|
if ($remainingPaths.Count -gt 0) {
|
|
Write-Status " - $($remainingPaths.Count) directory/directories still present" -Level WARNING
|
|
}
|
|
if ($remainingRegistry.Count -gt 0) {
|
|
Write-Status " - $($remainingRegistry.Count) registry key(s) still present" -Level WARNING
|
|
}
|
|
}
|
|
|
|
# Ask about restart
|
|
if (-not $Force) {
|
|
$restart = Read-Host "Would you like to restart the computer now? (Y/N)"
|
|
if ($restart -eq 'Y' -or $restart -eq 'y') {
|
|
Write-Status "Restarting computer in 10 seconds..." -Level WARNING
|
|
shutdown /r /t 10 /c "Restarting after CentraStage removal"
|
|
}
|
|
}
|
|
|
|
Write-Status "CentraStage removal script completed" -Level INFO
|