Public/Uninstall-WinslopFix.ps1

function Uninstall-WinslopFix {
    <#
    .SYNOPSIS
        Removes WinslopFix and all associated system artifacts.

    .DESCRIPTION
        Stops and removes the WinslopFix Scheduled Task, deletes deployed
        module files from ProgramData, and optionally removes the configuration
        file and re-enables any AI features that were disabled.

        This is a targeted uninstall — unlike the original Desinstalar script,
        it does NOT blindly kill all PowerShell processes.

    .PARAMETER RemoveConfig
        Also delete the config.json file. Without this switch, configuration
        is preserved for potential reinstallation.

    .PARAMETER EnableAIFeatures
        Re-enable all Copilot AI features (Recall, Click to Do, Windows AI)
        that may have been disabled during installation.

    .EXAMPLE
        Uninstall-WinslopFix

        Remove the Scheduled Task and deployed files, preserving config.

    .EXAMPLE
        Uninstall-WinslopFix -RemoveConfig -EnableAIFeatures

        Full removal including config and AI feature re-enablement.

    .EXAMPLE
        Uninstall-WinslopFix -WhatIf

        Preview all removal actions without executing them.

    .LINK
        https://github.com/DailenG/WinslopFix
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    param(
        [Parameter()]
        [switch]$RemoveConfig,

        [Parameter()]
        [switch]$EnableAIFeatures
    )

    process {
        Assert-Administrator

        $installPath = "$env:ProgramData\WinslopFix"
        $taskName    = 'WinslopFix'
        $taskPath    = '\WinslopFix\'

        # --- Step 1: Stop and remove the Scheduled Task ---
        $existingTask = Get-ScheduledTask -TaskName $taskName -TaskPath $taskPath -ErrorAction SilentlyContinue
        if ($existingTask) {
            if ($PSCmdlet.ShouldProcess("$taskPath$taskName", 'Stop and remove Scheduled Task')) {
                # Stop the task if running
                if ($existingTask.State -eq 'Running') {
                    Stop-ScheduledTask -TaskName $taskName -TaskPath $taskPath -ErrorAction SilentlyContinue
                    Write-Verbose 'Stopped running Scheduled Task.'
                }

                Unregister-ScheduledTask -TaskName $taskName -TaskPath $taskPath -Confirm:$false
                Write-Verbose "Removed Scheduled Task: $taskPath$taskName"
            }
        }
        else {
            Write-Verbose 'No WinslopFix Scheduled Task found.'
        }

        # --- Step 2: Remove deployed files ---
        if (Test-Path -LiteralPath $installPath) {
            if ($RemoveConfig) {
                # Remove everything
                if ($PSCmdlet.ShouldProcess($installPath, 'Remove all deployed files including config')) {
                    Remove-Item -LiteralPath $installPath -Recurse -Force -ErrorAction Stop
                    Write-Verbose "Removed installation directory: $installPath"
                }
            }
            else {
                # Preserve config.json, remove everything else
                if ($PSCmdlet.ShouldProcess($installPath, 'Remove deployed files (preserving config.json)')) {
                    $configFile = Join-Path $installPath 'config.json'
                    $hasConfig  = Test-Path -LiteralPath $configFile

                    Get-ChildItem -LiteralPath $installPath -Recurse -Force |
                        Where-Object { $_.FullName -ne $configFile } |
                        Sort-Object { $_.FullName.Length } -Descending |
                        Remove-Item -Force -Recurse -ErrorAction SilentlyContinue

                    if (-not $hasConfig) {
                        # No config to preserve, remove the directory itself
                        Remove-Item -LiteralPath $installPath -Force -ErrorAction SilentlyContinue
                    }

                    Write-Verbose "Removed deployed files from: $installPath (config preserved: $hasConfig)"
                }
            }
        }
        else {
            Write-Verbose "Installation directory not found: $installPath"
        }

        # --- Step 3: Remove Event Log source ---
        if ($PSCmdlet.ShouldProcess('WinslopFix', 'Remove Event Log source')) {
            try {
                if ([System.Diagnostics.EventLog]::SourceExists('WinslopFix')) {
                    Remove-EventLog -Source 'WinslopFix' -ErrorAction Stop
                    Write-Verbose 'Removed Event Log source: WinslopFix'
                }
            }
            catch {
                Write-Warning "Failed to remove Event Log source: $($_.Exception.Message)"
            }
        }

        # --- Step 4: Optionally re-enable AI features ---
        if ($EnableAIFeatures) {
            Write-Verbose 'Re-enabling Copilot AI features as requested...'
            Enable-CopilotAIFeature -Feature All
        }

        # --- Output summary ---
        [PSCustomObject]@{
            PSTypeName      = 'WinslopFix.UninstallResult'
            TaskRemoved     = [bool]$existingTask
            FilesRemoved    = $true
            ConfigPreserved = (-not $RemoveConfig)
            AIReenabled     = [bool]$EnableAIFeatures
            Timestamp       = (Get-Date).ToString('o')
        }
    }
}