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') } } } |