<#
.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
