docs: Update README and documentation for lxs multi-tool across Linux and Windows platforms.
This commit is contained in:
@@ -0,0 +1,483 @@
|
||||
<#
|
||||
LXS - Debloat and privacy (Windows)
|
||||
Description: Remove preinstalled apps you pick, and turn off telemetry,
|
||||
Cortana, ads, tracking tasks, Copilot and Recall.
|
||||
|
||||
Safety rules this script follows:
|
||||
- a restore point is created before the first change of a session
|
||||
- no app is removed unless you explicitly select it
|
||||
- the registry/service/task tweaks can be undone from the menu (option 8)
|
||||
- apps you remove come back only by reinstalling them from the Store
|
||||
|
||||
Repo: https://git.hyko.cx/hykocx/lxs
|
||||
#>
|
||||
|
||||
# Load LXS common library (colors, UI helpers, spinner, loggers, guards).
|
||||
# Prefers the sibling ..\lib\common.ps1 (repo checkout or installed layout) and
|
||||
# only hits the network when this script is run standalone.
|
||||
$LxsRawBase = if ($env:LXS_RAW_BASE) { $env:LXS_RAW_BASE } else { 'https://git.hyko.cx/hykocx/lxs/raw/branch/main' }
|
||||
if (-not $env:LXS_RAW_PLATFORM_BASE) { $env:LXS_RAW_PLATFORM_BASE = "$LxsRawBase/windows" }
|
||||
$LxsLibPath = if ($PSScriptRoot) { Join-Path $PSScriptRoot '..\lib\common.ps1' } else { $null }
|
||||
if ($LxsLibPath -and (Test-Path $LxsLibPath)) {
|
||||
. $LxsLibPath
|
||||
} else {
|
||||
try {
|
||||
$LxsLibSource = Invoke-RestMethod -Uri "$env:LXS_RAW_PLATFORM_BASE/lib/common.ps1" -UseBasicParsing -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Error 'Failed to fetch lib/common.ps1'
|
||||
exit 1
|
||||
}
|
||||
. ([scriptblock]::Create($LxsLibSource))
|
||||
}
|
||||
|
||||
$env:LXS_LOG_FILE = Join-Path (Get-LxsTempDir) 'lxs_debloat.log'
|
||||
|
||||
if (-not (Assert-LxsWindows)) { exit 1 }
|
||||
Assert-LxsAdmin -ScriptPath $PSCommandPath -Arguments $args
|
||||
|
||||
$script:LxsCheckpointDone = $false
|
||||
|
||||
# One restore point per session, created lazily before the first real change.
|
||||
function Assert-LxsCheckpoint {
|
||||
if ($script:LxsCheckpointDone) { return $true }
|
||||
Write-Host ''
|
||||
Write-LxsInfo 'Creating a restore point before changing anything...'
|
||||
$ok = New-LxsRestorePoint -Description 'LXS before debloat'
|
||||
if (-not $ok) {
|
||||
Write-Host ''
|
||||
Write-LxsWarn 'The restore point could not be created.'
|
||||
if (-not (Confirm-LxsAction -Question 'Continue anyway, without a rollback point?')) {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
$script:LxsCheckpointDone = $true
|
||||
return $true
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Preinstalled apps
|
||||
#
|
||||
# Only packages on this list are ever offered. Anything not listed here —
|
||||
# including the Store, App Installer (winget), Terminal, Defender UI, the
|
||||
# VCLibs/.NET runtime frameworks and every driver package — is left alone,
|
||||
# because removing those breaks Windows or LXS itself.
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
$LxsRemovableApps = @(
|
||||
@{ Pattern = 'Microsoft.3DBuilder'; Label = '3D Builder' }
|
||||
@{ Pattern = 'Microsoft.549981C3F5F10'; Label = 'Cortana' }
|
||||
@{ Pattern = 'Microsoft.BingFinance'; Label = 'Bing Finance' }
|
||||
@{ Pattern = 'Microsoft.BingNews'; Label = 'Bing News' }
|
||||
@{ Pattern = 'Microsoft.BingSports'; Label = 'Bing Sports' }
|
||||
@{ Pattern = 'Microsoft.BingWeather'; Label = 'Weather' }
|
||||
@{ Pattern = 'Microsoft.BingSearch'; Label = 'Web Search (Bing)' }
|
||||
@{ Pattern = 'Microsoft.GetHelp'; Label = 'Get Help' }
|
||||
@{ Pattern = 'Microsoft.Getstarted'; Label = 'Tips / Get Started' }
|
||||
@{ Pattern = 'Microsoft.Messaging'; Label = 'Messaging' }
|
||||
@{ Pattern = 'Microsoft.Microsoft3DViewer'; Label = '3D Viewer' }
|
||||
@{ Pattern = 'Microsoft.MicrosoftJournal'; Label = 'Journal' }
|
||||
@{ Pattern = 'Microsoft.MicrosoftOfficeHub'; Label = 'Office Hub' }
|
||||
@{ Pattern = 'Microsoft.MicrosoftSolitaireCollection'; Label = 'Solitaire Collection' }
|
||||
@{ Pattern = 'Microsoft.MixedReality.Portal'; Label = 'Mixed Reality Portal' }
|
||||
@{ Pattern = 'Microsoft.NetworkSpeedTest'; Label = 'Network Speed Test' }
|
||||
@{ Pattern = 'Microsoft.News'; Label = 'News' }
|
||||
@{ Pattern = 'Microsoft.Office.OneNote'; Label = 'OneNote (Store version)' }
|
||||
@{ Pattern = 'Microsoft.Office.Sway'; Label = 'Sway' }
|
||||
@{ Pattern = 'Microsoft.OneConnect'; Label = 'Mobile Plans' }
|
||||
@{ Pattern = 'Microsoft.People'; Label = 'People' }
|
||||
@{ Pattern = 'Microsoft.PowerAutomateDesktop'; Label = 'Power Automate Desktop' }
|
||||
@{ Pattern = 'Microsoft.Print3D'; Label = 'Print 3D' }
|
||||
@{ Pattern = 'Microsoft.SkypeApp'; Label = 'Skype' }
|
||||
@{ Pattern = 'Microsoft.Todos'; Label = 'Microsoft To Do' }
|
||||
@{ Pattern = 'Microsoft.Wallet'; Label = 'Wallet' }
|
||||
@{ Pattern = 'Microsoft.WindowsAlarms'; Label = 'Alarms & Clock' }
|
||||
@{ Pattern = 'Microsoft.WindowsFeedbackHub'; Label = 'Feedback Hub' }
|
||||
@{ Pattern = 'Microsoft.WindowsMaps'; Label = 'Maps' }
|
||||
@{ Pattern = 'Microsoft.WindowsSoundRecorder'; Label = 'Sound Recorder' }
|
||||
@{ Pattern = 'Microsoft.Xbox.TCUI'; Label = 'Xbox TCUI' }
|
||||
@{ Pattern = 'Microsoft.XboxApp'; Label = 'Xbox Console Companion' }
|
||||
@{ Pattern = 'Microsoft.XboxGameOverlay'; Label = 'Xbox Game Overlay' }
|
||||
@{ Pattern = 'Microsoft.XboxGamingOverlay'; Label = 'Xbox Game Bar' }
|
||||
@{ Pattern = 'Microsoft.XboxIdentityProvider'; Label = 'Xbox Identity Provider' }
|
||||
@{ Pattern = 'Microsoft.XboxSpeechToTextOverlay'; Label = 'Xbox Speech To Text' }
|
||||
@{ Pattern = 'Microsoft.YourPhone'; Label = 'Phone Link' }
|
||||
@{ Pattern = 'Microsoft.ZuneMusic'; Label = 'Media Player / Groove Music' }
|
||||
@{ Pattern = 'Microsoft.ZuneVideo'; Label = 'Movies & TV' }
|
||||
@{ Pattern = 'MicrosoftTeams'; Label = 'Teams (personal / chat)' }
|
||||
@{ Pattern = 'MSTeams'; Label = 'Teams (new client)' }
|
||||
@{ Pattern = 'Clipchamp.Clipchamp'; Label = 'Clipchamp' }
|
||||
@{ Pattern = 'Microsoft.Copilot'; Label = 'Copilot app' }
|
||||
@{ Pattern = 'Microsoft.WindowsFamilySafety'; Label = 'Family Safety' }
|
||||
@{ Pattern = 'SpotifyAB.SpotifyMusic'; Label = 'Spotify (OEM stub)' }
|
||||
@{ Pattern = 'Disney.37853FC22B2CE'; Label = 'Disney+ (OEM stub)' }
|
||||
)
|
||||
|
||||
function Get-LxsInstalledBloat {
|
||||
$found = @()
|
||||
foreach ($entry in $LxsRemovableApps) {
|
||||
try {
|
||||
$pkgs = @(Get-AppxPackage -Name $entry.Pattern -ErrorAction SilentlyContinue)
|
||||
} catch {
|
||||
$pkgs = @()
|
||||
}
|
||||
if ($pkgs.Count -gt 0) {
|
||||
$found += [pscustomobject]@{
|
||||
Label = $entry.Label
|
||||
Pattern = $entry.Pattern
|
||||
Name = $pkgs[0].Name
|
||||
Version = $pkgs[0].Version
|
||||
}
|
||||
}
|
||||
}
|
||||
return $found
|
||||
}
|
||||
|
||||
function Remove-LxsSelectedApps {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'REMOVE PREINSTALLED APPS'
|
||||
Write-Host ''
|
||||
Write-LxsInfo 'Scanning installed packages...'
|
||||
$found = @(Get-LxsInstalledBloat)
|
||||
Write-Host ''
|
||||
|
||||
if ($found.Count -eq 0) {
|
||||
Write-LxsOk 'None of the known preinstalled apps are present.'
|
||||
return
|
||||
}
|
||||
|
||||
for ($i = 0; $i -lt $found.Count; $i++) {
|
||||
Write-Host (" $($script:Cyan)[{0,2}]$($script:NC) $($script:White){1,-32}$($script:NC) $($script:Gray){2}$($script:NC)" -f `
|
||||
($i + 1), $found[$i].Label, $found[$i].Name)
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host "$($script:Gray)Enter the numbers to remove, separated by commas (e.g. 1,4,7),$($script:NC)"
|
||||
Write-Host "$($script:Gray)or 'all' for every entry above. Empty cancels — nothing is removed$($script:NC)"
|
||||
Write-Host "$($script:Gray)unless you name it here.$($script:NC)"
|
||||
Write-Host ''
|
||||
$selection = Read-Host -Prompt 'Selection'
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($selection)) {
|
||||
Write-LxsInfo 'Cancelled — nothing removed.'
|
||||
return
|
||||
}
|
||||
|
||||
$targets = @()
|
||||
if ($selection.Trim() -ieq 'all') {
|
||||
$targets = $found
|
||||
} else {
|
||||
foreach ($part in ($selection -split ',')) {
|
||||
$part = $part.Trim()
|
||||
if ($part -notmatch '^\d+$') {
|
||||
Write-LxsErr "Not a number: $part"
|
||||
return
|
||||
}
|
||||
$idx = [int]$part - 1
|
||||
if ($idx -lt 0 -or $idx -ge $found.Count) {
|
||||
Write-LxsErr "Out of range: $part"
|
||||
return
|
||||
}
|
||||
$targets += $found[$idx]
|
||||
}
|
||||
}
|
||||
$targets = @($targets | Sort-Object Name -Unique)
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'These will be removed for the current user:'
|
||||
foreach ($t in $targets) { Write-Host " - $($t.Label)" }
|
||||
Write-Host ''
|
||||
Write-Host "$($script:Gray)They can be reinstalled later from the Microsoft Store.$($script:NC)"
|
||||
Write-Host ''
|
||||
if (-not (Confirm-LxsAction -Question "Remove $($targets.Count) app(s)?")) {
|
||||
Write-LxsInfo 'Cancelled.'
|
||||
return
|
||||
}
|
||||
if (-not (Assert-LxsCheckpoint)) { return }
|
||||
|
||||
$alsoProvisioned = Confirm-LxsAction -Question 'Also remove them from the image, so new user accounts do not get them?'
|
||||
|
||||
Write-Host ''
|
||||
foreach ($t in $targets) {
|
||||
try {
|
||||
Get-AppxPackage -Name $t.Pattern -ErrorAction Stop | Remove-AppxPackage -ErrorAction Stop
|
||||
Write-LxsOk "$($t.Label) removed"
|
||||
} catch {
|
||||
Write-LxsWarn "$($t.Label): $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
if ($alsoProvisioned) {
|
||||
try {
|
||||
$prov = @(Get-AppxProvisionedPackage -Online -ErrorAction Stop |
|
||||
Where-Object { $_.DisplayName -like $t.Pattern })
|
||||
foreach ($p in $prov) {
|
||||
Remove-AppxProvisionedPackage -Online -PackageName $p.PackageName -ErrorAction Stop | Out-Null
|
||||
Write-Host "$($script:Gray) also removed from the image$($script:NC)"
|
||||
}
|
||||
} catch {
|
||||
Write-LxsWarn "$($t.Label): could not remove the provisioned package."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Privacy tweaks
|
||||
#
|
||||
# Every entry carries the value to set and the value to restore, so option 8
|
||||
# can undo exactly what option 2-6 did. Default = $null means "delete the
|
||||
# value", which is what returns a policy key to its Windows default.
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
$LxsTweaks = @(
|
||||
# --- telemetry ---
|
||||
@{ Group = 'telemetry'; Label = 'Diagnostic data set to the minimum';
|
||||
Path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection'; Name = 'AllowTelemetry'; Value = 0; Default = $null }
|
||||
@{ Group = 'telemetry'; Label = 'Do not send device names with telemetry';
|
||||
Path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection'; Name = 'AllowDeviceNameInTelemetry'; Value = 0; Default = $null }
|
||||
@{ Group = 'telemetry'; Label = 'Advertising ID disabled';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo'; Name = 'Enabled'; Value = 0; Default = 1 }
|
||||
@{ Group = 'telemetry'; Label = 'App launch tracking disabled';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced'; Name = 'Start_TrackProgs'; Value = 0; Default = 1 }
|
||||
@{ Group = 'telemetry'; Label = 'Feedback requests disabled';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Siuf\Rules'; Name = 'NumberOfSIUFInPeriod'; Value = 0; Default = $null }
|
||||
|
||||
# --- cortana / search ---
|
||||
@{ Group = 'cortana'; Label = 'Cortana disabled';
|
||||
Path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search'; Name = 'AllowCortana'; Value = 0; Default = $null }
|
||||
@{ Group = 'cortana'; Label = 'Web results in Start disabled';
|
||||
Path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search'; Name = 'DisableWebSearch'; Value = 1; Default = $null }
|
||||
@{ Group = 'cortana'; Label = 'Connected web search disabled';
|
||||
Path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search'; Name = 'ConnectedSearchUseWeb'; Value = 0; Default = $null }
|
||||
@{ Group = 'cortana'; Label = 'Search highlights disabled';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings'; Name = 'IsDynamicSearchBoxEnabled'; Value = 0; Default = 1 }
|
||||
|
||||
# --- ads and suggestions ---
|
||||
@{ Group = 'ads'; Label = 'Start menu app suggestions off';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager'; Name = 'SystemPaneSuggestionsEnabled'; Value = 0; Default = 1 }
|
||||
@{ Group = 'ads'; Label = 'Silent install of promoted apps off';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager'; Name = 'SilentInstalledAppsEnabled'; Value = 0; Default = 1 }
|
||||
@{ Group = 'ads'; Label = 'Lock screen spotlight ads off';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager'; Name = 'RotatingLockScreenOverlayEnabled'; Value = 0; Default = 1 }
|
||||
@{ Group = 'ads'; Label = 'Windows tips and tricks off';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager'; Name = 'SubscribedContent-338389Enabled'; Value = 0; Default = 1 }
|
||||
@{ Group = 'ads'; Label = 'Suggested content in Settings off';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager'; Name = 'SubscribedContent-338393Enabled'; Value = 0; Default = 1 }
|
||||
@{ Group = 'ads'; Label = 'Welcome experience after updates off';
|
||||
Path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager'; Name = 'SubscribedContent-310093Enabled'; Value = 0; Default = 1 }
|
||||
|
||||
# --- copilot / recall ---
|
||||
@{ Group = 'ai'; Label = 'Windows Copilot turned off';
|
||||
Path = 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot'; Name = 'TurnOffWindowsCopilot'; Value = 1; Default = $null }
|
||||
@{ Group = 'ai'; Label = 'Windows Copilot turned off (machine-wide)';
|
||||
Path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot'; Name = 'TurnOffWindowsCopilot'; Value = 1; Default = $null }
|
||||
@{ Group = 'ai'; Label = 'Recall snapshots disabled';
|
||||
Path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI'; Name = 'DisableAIDataAnalysis'; Value = 1; Default = $null }
|
||||
@{ Group = 'ai'; Label = 'Recall snapshots disabled (per user)';
|
||||
Path = 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI'; Name = 'DisableAIDataAnalysis'; Value = 1; Default = $null }
|
||||
)
|
||||
|
||||
$LxsTrackingTasks = @(
|
||||
'\Microsoft\Windows\Application Experience\Microsoft Compatibility Appraisal',
|
||||
'\Microsoft\Windows\Application Experience\ProgramDataUpdater',
|
||||
'\Microsoft\Windows\Application Experience\StartupAppTask',
|
||||
'\Microsoft\Windows\Customer Experience Improvement Program\Consolidator',
|
||||
'\Microsoft\Windows\Customer Experience Improvement Program\UsbCeip',
|
||||
'\Microsoft\Windows\Autochk\Proxy',
|
||||
'\Microsoft\Windows\Feedback\Siuf\DmClient',
|
||||
'\Microsoft\Windows\Feedback\Siuf\DmClientOnScenarioDownload'
|
||||
)
|
||||
|
||||
$LxsTrackingServices = @(
|
||||
@{ Name = 'DiagTrack'; Label = 'Connected User Experiences and Telemetry'; Default = 'Automatic' },
|
||||
@{ Name = 'dmwappushservice'; Label = 'WAP Push Message Routing'; Default = 'Manual' }
|
||||
)
|
||||
|
||||
function Invoke-LxsTweakGroup {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Group,
|
||||
[Parameter(Mandatory = $true)][string]$Title
|
||||
)
|
||||
$entries = @($LxsTweaks | Where-Object { $_.Group -eq $Group })
|
||||
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title $Title
|
||||
Write-Host ''
|
||||
Write-Host 'The following settings will be changed:'
|
||||
foreach ($e in $entries) { Write-Host " - $($e.Label)" }
|
||||
if ($Group -eq 'telemetry') {
|
||||
Write-Host ' - Telemetry services disabled (DiagTrack, dmwappushservice)'
|
||||
Write-Host ' - Tracking scheduled tasks disabled'
|
||||
}
|
||||
Write-Host ''
|
||||
Write-Host "$($script:Gray)All of this is reversible from menu option 8.$($script:NC)"
|
||||
Write-Host ''
|
||||
if (-not (Confirm-LxsAction -Question 'Apply?')) {
|
||||
Write-LxsInfo 'Cancelled.'
|
||||
return
|
||||
}
|
||||
if (-not (Assert-LxsCheckpoint)) { return }
|
||||
|
||||
Write-Host ''
|
||||
foreach ($e in $entries) {
|
||||
if (Set-LxsRegistryValue -Path $e.Path -Name $e.Name -Value $e.Value) {
|
||||
Write-LxsOk $e.Label
|
||||
}
|
||||
}
|
||||
|
||||
if ($Group -ne 'telemetry') { return }
|
||||
|
||||
Write-Host ''
|
||||
foreach ($svc in $LxsTrackingServices) {
|
||||
try {
|
||||
$s = Get-Service -Name $svc.Name -ErrorAction Stop
|
||||
if ($s.Status -eq 'Running') { Stop-Service -Name $svc.Name -Force -ErrorAction SilentlyContinue }
|
||||
Set-Service -Name $svc.Name -StartupType Disabled -ErrorAction Stop
|
||||
Write-LxsOk "$($svc.Label) service disabled"
|
||||
} catch {
|
||||
Write-LxsWarn "$($svc.Label): $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
$disabled = 0
|
||||
foreach ($taskPath in $LxsTrackingTasks) {
|
||||
$leaf = Split-Path $taskPath -Leaf
|
||||
$parent = (Split-Path $taskPath -Parent) + '\'
|
||||
try {
|
||||
Disable-ScheduledTask -TaskName $leaf -TaskPath $parent -ErrorAction Stop | Out-Null
|
||||
$disabled++
|
||||
} catch {
|
||||
# Absent on this edition/build — nothing to disable.
|
||||
}
|
||||
}
|
||||
Write-LxsOk "$disabled tracking scheduled task(s) disabled"
|
||||
}
|
||||
|
||||
function Restore-LxsTweaks {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'REVERT PRIVACY TWEAKS'
|
||||
Write-Host ''
|
||||
Write-Host 'This restores every registry value, service and scheduled task that'
|
||||
Write-Host 'this script changes, back to the Windows default.'
|
||||
Write-Host ''
|
||||
Write-Host "$($script:Gray)Apps you removed are NOT restored — reinstall them from the Store.$($script:NC)"
|
||||
Write-Host ''
|
||||
if (-not (Confirm-LxsAction -Question 'Revert the privacy tweaks?')) {
|
||||
Write-LxsInfo 'Cancelled.'
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
foreach ($e in $LxsTweaks) {
|
||||
if ($null -eq $e.Default) {
|
||||
try {
|
||||
if (Test-Path $e.Path) {
|
||||
Remove-ItemProperty -Path $e.Path -Name $e.Name -ErrorAction Stop
|
||||
}
|
||||
Write-LxsOk "$($e.Label) — policy removed"
|
||||
} catch {
|
||||
# Already absent: that is the default state we wanted.
|
||||
}
|
||||
} else {
|
||||
if (Set-LxsRegistryValue -Path $e.Path -Name $e.Name -Value $e.Default) {
|
||||
Write-LxsOk "$($e.Label) — restored to default"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
foreach ($svc in $LxsTrackingServices) {
|
||||
try {
|
||||
Set-Service -Name $svc.Name -StartupType $svc.Default -ErrorAction Stop
|
||||
Write-LxsOk "$($svc.Label) service restored to $($svc.Default)"
|
||||
} catch {
|
||||
Write-LxsWarn "$($svc.Label): $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
$enabled = 0
|
||||
foreach ($taskPath in $LxsTrackingTasks) {
|
||||
$leaf = Split-Path $taskPath -Leaf
|
||||
$parent = (Split-Path $taskPath -Parent) + '\'
|
||||
try {
|
||||
Enable-ScheduledTask -TaskName $leaf -TaskPath $parent -ErrorAction Stop | Out-Null
|
||||
$enabled++
|
||||
} catch {
|
||||
# Not present on this build.
|
||||
}
|
||||
}
|
||||
Write-LxsOk "$enabled scheduled task(s) re-enabled"
|
||||
Write-Host ''
|
||||
Write-LxsWarn 'Sign out and back in for the per-user settings to take effect.'
|
||||
}
|
||||
|
||||
function Show-LxsDebloatStatus {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'CURRENT STATE'
|
||||
Write-Host ''
|
||||
$installed = @(Get-LxsInstalledBloat)
|
||||
Write-Host " Known preinstalled apps still present : $($installed.Count) / $($LxsRemovableApps.Count)"
|
||||
|
||||
$applied = 0
|
||||
foreach ($e in $LxsTweaks) {
|
||||
try {
|
||||
$current = (Get-ItemProperty -Path $e.Path -Name $e.Name -ErrorAction Stop).($e.Name)
|
||||
if ($current -eq $e.Value) { $applied++ }
|
||||
} catch {
|
||||
# Value absent -> tweak not applied.
|
||||
}
|
||||
}
|
||||
Write-Host " Privacy tweaks applied : $applied / $($LxsTweaks.Count)"
|
||||
|
||||
foreach ($svc in $LxsTrackingServices) {
|
||||
try {
|
||||
$s = Get-Service -Name $svc.Name -ErrorAction Stop
|
||||
Write-Host " $($svc.Name.PadRight(38)): $($s.Status) / $($s.StartType)"
|
||||
} catch {
|
||||
Write-Host " $($svc.Name.PadRight(38)): not present"
|
||||
}
|
||||
}
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
function Show-LxsDebloatMenu {
|
||||
while ($true) {
|
||||
Clear-Host
|
||||
Show-LxsBoxTop -Title 'DEBLOAT & PRIVACY' -Right 'ADMIN'
|
||||
Write-Host ''
|
||||
Show-LxsMenuItem '1' 'Show current state'
|
||||
Show-LxsMenuItem '2' 'Remove preinstalled apps' 'you pick each one'
|
||||
Show-LxsMenuItem '3' 'Disable telemetry' 'policy, services, tasks'
|
||||
Show-LxsMenuItem '4' 'Disable Cortana & web search'
|
||||
Show-LxsMenuItem '5' 'Disable ads & suggestions'
|
||||
Show-LxsMenuItem '6' 'Disable Copilot & Recall'
|
||||
Show-LxsMenuItem '7' 'Create a restore point' 'before doing anything'
|
||||
Show-LxsMenuItem '8' 'Revert privacy tweaks' 'undo 3-6'
|
||||
Show-LxsMenuItem '0' 'Back' '' -Exit
|
||||
Write-Host ''
|
||||
Show-LxsBoxBottom
|
||||
Write-Host ''
|
||||
$choice = Read-LxsChoice
|
||||
Write-Host ''
|
||||
|
||||
switch ($choice) {
|
||||
'1' { Show-LxsDebloatStatus; Read-LxsEnter }
|
||||
'2' { Remove-LxsSelectedApps; Read-LxsEnter }
|
||||
'3' { Invoke-LxsTweakGroup -Group 'telemetry' -Title 'DISABLE TELEMETRY'; Read-LxsEnter }
|
||||
'4' { Invoke-LxsTweakGroup -Group 'cortana' -Title 'DISABLE CORTANA & WEB SEARCH'; Read-LxsEnter }
|
||||
'5' { Invoke-LxsTweakGroup -Group 'ads' -Title 'DISABLE ADS & SUGGESTIONS'; Read-LxsEnter }
|
||||
'6' { Invoke-LxsTweakGroup -Group 'ai' -Title 'DISABLE COPILOT & RECALL'; Read-LxsEnter }
|
||||
'7' {
|
||||
if (New-LxsRestorePoint -Description 'LXS manual checkpoint') { $script:LxsCheckpointDone = $true }
|
||||
Read-LxsEnter
|
||||
}
|
||||
'8' { Restore-LxsTweaks; Read-LxsEnter }
|
||||
'0' { return }
|
||||
default { Write-LxsErr 'Invalid protocol. Select 0-8.'; Start-Sleep -Seconds 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Show-LxsDebloatMenu
|
||||
exit 75
|
||||
Reference in New Issue
Block a user