diff --git a/Config/Features.json b/Config/Features.json index 45f0a38..1221e54 100644 --- a/Config/Features.json +++ b/Config/Features.json @@ -393,9 +393,9 @@ "ToolTip": "This setting disables telemetry, diagnostic data collection, activity history, app-launch tracking, targeted ads and more. It limits the data that is sent to Microsoft about your device and usage. If you are a Windows Insider, updates may be blocked until optional diagnostic data collection is turned back on.", "Category": "Privacy & Suggested Content", "RegistryKey": "Disable_Telemetry.reg", - "ApplyText": "Disabling telemetry, diagnostic data, activity history, app-launch tracking and targeted ads", + "ApplyText": "Disabling telemetry and diagnostic data collection", "UndoLabel": "Enable telemetry, tracking & targeted ads", - "ApplyUndoText": "Enabling telemetry, diagnostic data, activity history, app-launch tracking and targeted ads", + "ApplyUndoText": "Enabling telemetry and diagnostic data collection", "RegistryUndoKey": "Enable_Telemetry.reg", "MinVersion": null, "MaxVersion": null diff --git a/Scripts/Features/ExecuteChanges.ps1 b/Scripts/Features/ExecuteChanges.ps1 index 828cc41..8309fe9 100644 --- a/Scripts/Features/ExecuteChanges.ps1 +++ b/Scripts/Features/ExecuteChanges.ps1 @@ -26,6 +26,10 @@ function ExecuteParameter { # Also remove the app package for Copilot RemoveApps @('Microsoft.Copilot') } + 'DisableTelemetry' { + # Also disable telemetry scheduled tasks + Disable-TelemetryScheduledTasks + } } return } @@ -245,9 +249,9 @@ function ExecuteAllChanges { if ($f -and $f.RegistryUndoKey) { ImportRegistryFile "> $applyUndoText" (Resolve-UndoRegFilePath $f.RegistryUndoKey) - } else { - Invoke-UndoFeatureAction -FeatureId $featureId } + + Invoke-UndoFeatureAction -FeatureId $featureId } if ($script:RegistryImportFailures -gt 0) { @@ -302,9 +306,9 @@ function Invoke-UndoFeatureAction { Write-Host "" return } - default { - Write-Host "> No undo action defined for $FeatureId, skipping..." -ForegroundColor Yellow - Write-Host "" + 'DisableTelemetry' { + # Also re-enable telemetry scheduled tasks + Enable-TelemetryScheduledTasks return } } diff --git a/Scripts/Features/TelemetryScheduledTasks.ps1 b/Scripts/Features/TelemetryScheduledTasks.ps1 new file mode 100644 index 0000000..d780fd8 --- /dev/null +++ b/Scripts/Features/TelemetryScheduledTasks.ps1 @@ -0,0 +1,128 @@ +# List of known Windows telemetry-related scheduled tasks +<# + .SYNOPSIS + Returns the list of known Windows telemetry-related scheduled tasks. + + .DESCRIPTION + Returns an array of hashtables, each with a Path and Name key, representing + scheduled tasks that collect or report telemetry data on Windows. + + .EXAMPLE + Get-TelemetryScheduledTasks +#> +function Get-TelemetryScheduledTasks { + return @( + @{ Path = "\Microsoft\Windows\Application Experience\"; Name = "Microsoft Compatibility Appraiser" }, + @{ Path = "\Microsoft\Windows\Application Experience\"; Name = "Microsoft Compatibility Appraiser Exp" }, + @{ Path = "\Microsoft\Windows\Application Experience\"; Name = "ProgramDataUpdater" }, + @{ Path = "\Microsoft\Windows\Application Experience\"; Name = "StartupAppTask" }, + @{ Path = "\Microsoft\Windows\Customer Experience Improvement Program\"; Name = "Consolidator" }, + @{ Path = "\Microsoft\Windows\Customer Experience Improvement Program\"; Name = "UsbCeip" }, + @{ Path = "\Microsoft\Windows\DiskDiagnostic\"; Name = "Microsoft-Windows-DiskDiagnosticDataCollector" }, + @{ Path = "\Microsoft\Windows\Autochk\"; Name = "Proxy" } + ) +} + +<# + .SYNOPSIS + Disables known Windows telemetry-related scheduled tasks. + + .DESCRIPTION + Iterates over a predefined list of Windows scheduled tasks associated with + telemetry and disables each one that exists and is not already disabled. + Supports -WhatIf to preview changes without applying them. + + .EXAMPLE + Disable-TelemetryScheduledTasks +#> +function Disable-TelemetryScheduledTasks { + Write-Host "> Disabling telemetry scheduled tasks..." + $tasks = Get-TelemetryScheduledTasks + + foreach ($task in $tasks) { + if ($script:Params.ContainsKey("WhatIf")) { + Write-Host "[WhatIf] Disable Scheduled Task: $($task.Path)$($task.Name)" -ForegroundColor Cyan + continue + } + + $result = Invoke-NonBlocking -ScriptBlock { + param($path, $name) + Import-Module ScheduledTasks -ErrorAction SilentlyContinue + $taskObj = Get-ScheduledTask -TaskPath $path -TaskName $name -ErrorAction SilentlyContinue + if (-not $taskObj) { + return @{ Success = $true; Status = 'NotFound' } + } + if ($taskObj.State -ne 'Disabled') { + try { + Disable-ScheduledTask -TaskPath $path -TaskName $name -ErrorAction Stop | Out-Null + return @{ Success = $true; Status = 'Disabled' } + } + catch { + return @{ Success = $false; Status = 'Error'; Error = $_.Exception.Message } + } + } + return @{ Success = $true; Status = 'AlreadyDisabled' } + } -ArgumentList @($task.Path, $task.Name) + + switch ($result.Status) { + 'Disabled' { Write-Host "Disabled Scheduled Task: $($task.Path)$($task.Name)" } + 'AlreadyDisabled' { Write-Host "Scheduled Task $($task.Path)$($task.Name) is already disabled" -ForegroundColor DarkGray } + 'NotFound' { Write-Host "Scheduled Task $($task.Path)$($task.Name) not found" -ForegroundColor DarkGray } + 'Error' { Write-Host "Failed to disable Scheduled Task: $($task.Path)$($task.Name) - $($result.Error)" -ForegroundColor Yellow } + } + } + + Write-Host "" +} + +<# + .SYNOPSIS + Enables known Windows telemetry-related scheduled tasks. + + .DESCRIPTION + Iterates over a predefined list of Windows scheduled tasks associated with + telemetry and enables each one that exists and is currently disabled. + Supports -WhatIf to preview changes without applying them. + + .EXAMPLE + Enable-TelemetryScheduledTasks +#> +function Enable-TelemetryScheduledTasks { + Write-Host "> Enabling telemetry scheduled tasks..." + $tasks = Get-TelemetryScheduledTasks + + foreach ($task in $tasks) { + if ($script:Params.ContainsKey("WhatIf")) { + Write-Host "[WhatIf] Enable Scheduled Task: $($task.Path)$($task.Name)" -ForegroundColor Cyan + continue + } + + $result = Invoke-NonBlocking -ScriptBlock { + param($path, $name) + Import-Module ScheduledTasks -ErrorAction SilentlyContinue + $taskObj = Get-ScheduledTask -TaskPath $path -TaskName $name -ErrorAction SilentlyContinue + if (-not $taskObj) { + return @{ Success = $true; Status = 'NotFound' } + } + if ($taskObj.State -eq 'Disabled') { + try { + Enable-ScheduledTask -TaskPath $path -TaskName $name -ErrorAction Stop | Out-Null + return @{ Success = $true; Status = 'Enabled' } + } + catch { + return @{ Success = $false; Status = 'Error'; Error = $_.Exception.Message } + } + } + return @{ Success = $true; Status = 'AlreadyEnabled' } + } -ArgumentList @($task.Path, $task.Name) + + switch ($result.Status) { + 'Enabled' { Write-Host "Enabled Scheduled Task: $($task.Path)$($task.Name)" } + 'AlreadyEnabled' { Write-Host "Scheduled Task $($task.Path)$($task.Name) is already enabled." -ForegroundColor DarkGray } + 'NotFound' { Write-Host "Scheduled Task $($task.Path)$($task.Name) not found." -ForegroundColor DarkGray } + 'Error' { Write-Host "Failed to enable Scheduled Task: $($task.Path)$($task.Name) - $($result.Error)" -ForegroundColor Yellow } + } + } + + Write-Host "" +} diff --git a/Win11Debloat.ps1 b/Win11Debloat.ps1 index 5c627cf..93fc49f 100644 --- a/Win11Debloat.ps1 +++ b/Win11Debloat.ps1 @@ -301,6 +301,7 @@ if (-not $script:WingetInstalled -and -not $Silent) { . "$PSScriptRoot/Scripts/Features/RestoreRegistryApplyState.ps1" . "$PSScriptRoot/Scripts/Features/RestoreRegistryBackup.ps1" . "$PSScriptRoot/Scripts/Features/DisableStoreSearchSuggestions.ps1" +. "$PSScriptRoot/Scripts/Features/TelemetryScheduledTasks.ps1" . "$PSScriptRoot/Scripts/Features/WindowsOptionalFeatures.ps1" . "$PSScriptRoot/Scripts/Features/ImportRegistryFile.ps1" . "$PSScriptRoot/Scripts/Features/ReplaceStartMenu.ps1"