diff --git a/README.fr.md b/README.fr.md index dd0a96a..5065f26 100644 --- a/README.fr.md +++ b/README.fr.md @@ -21,7 +21,7 @@ Petite boîte à outils Windows pour installer des packs de logiciels libres ave | --- | --- | | [`powershell/libres-softwares-install.ps1`](./powershell/libres-softwares-install.ps1) | Installateur interactif pour une liste de logiciels sélectionnés. | | [`powershell/Winget-Remove-BuiltInApps.ps1`](./powershell/Winget-Remove-BuiltInApps.ps1) | Suppression de certaines applications Windows intégrées pour l'utilisateur courant avec winget. | -| [`powershell/Remove-BuiltInApps.ps1`](./powershell/Remove-BuiltInApps.ps1) | Suppression de certaines applications Appx intégrées sans winget, y compris les packages provisionnés pour les nouveaux utilisateurs. | +| [`powershell/Remove-BuiltInApps.ps1`](./powershell/Remove-BuiltInApps.ps1) | Suppression de certaines applications Appx intégrées sans winget avec blocages registre pour les futurs utilisateurs. | | [`winget/libre-soft-start-pack.yaml`](./winget/libre-soft-start-pack.yaml) | Pack automatisé de départ : Firefox ESR, 7-Zip et VLC. | | [`winget/libre-soft-base-libreoffice.yaml`](./winget/libre-soft-base-libreoffice.yaml) | Pack de départ avec LibreOffice. | | [`winget/libre-soft-base-onlyoffice.yaml`](./winget/libre-soft-base-onlyoffice.yaml) | Pack de départ avec ONLYOFFICE. | @@ -87,12 +87,14 @@ winget configure --file .\winget\libre-soft-start-pack.yaml --accept-configurati ## Supprimer des Applications Intégrées -Utilise le script de nettoyage Appx pour supprimer certaines applications intégrées sans winget et éviter leur provisionnement pour les nouveaux utilisateurs. +Utilise le script de nettoyage Appx pour supprimer certaines applications intégrées sans winget et limiter leur reprovisionnement pour les nouveaux utilisateurs. ```powershell powershell -ExecutionPolicy Bypass -File .\powershell\Remove-BuiltInApps.ps1 ``` +Le script supprime les packages Appx installés et provisionnés, désactive les expériences consommateur Microsoft, met à jour les paramètres `ContentDeliveryManager` du profil utilisateur par défaut et écrit des marqueurs registre de déprovisionnement Appx. + OneDrive n'est généralement pas un package Appx. Pour appeler aussi le programme de désinstallation intégré de OneDrive, ajoute `-IncludeOneDrive` : ```powershell @@ -105,7 +107,7 @@ L'ancien script basé sur winget reste disponible, mais il ne cible que l'utilis powershell -ExecutionPolicy Bypass -File .\powershell\Winget-Remove-BuiltInApps.ps1 ``` -Les applications visées incluent des composants Xbox, Outlook for Windows, Hub de commentaires, Power Automate, Sticky Notes, Météo, Teams, Microsoft To Do, des applications Bing, Clipchamp, Windows Web Experience Pack et des packages intégrés associés. +Lance ce script avant de créer le nouveau profil Windows, puis redémarre Windows. Les applications visées incluent des composants Xbox, Outlook for Windows, Hub de commentaires, Power Automate, Sticky Notes, Météo, Teams, Microsoft To Do, des applications Bing, Clipchamp, Windows Web Experience Pack et des packages intégrés associés. ## Note de Maintenance diff --git a/README.md b/README.md index 564c67d..be485fd 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Small Windows toolkit to install libre software packs with `winget` and remove s | --- | --- | | [`powershell/libres-softwares-install.ps1`](./powershell/libres-softwares-install.ps1) | Interactive installer for a curated list of applications. | | [`powershell/Winget-Remove-BuiltInApps.ps1`](./powershell/Winget-Remove-BuiltInApps.ps1) | Removes selected built-in Windows applications for the current user with winget. | -| [`powershell/Remove-BuiltInApps.ps1`](./powershell/Remove-BuiltInApps.ps1) | Removes selected built-in Appx applications without winget, including provisioned packages for new users. | +| [`powershell/Remove-BuiltInApps.ps1`](./powershell/Remove-BuiltInApps.ps1) | Removes selected built-in Appx applications without winget and writes registry blocks for future users. | | [`winget/libre-soft-start-pack.yaml`](./winget/libre-soft-start-pack.yaml) | Automated starter pack: Firefox ESR, 7-Zip and VLC. | | [`winget/libre-soft-base-libreoffice.yaml`](./winget/libre-soft-base-libreoffice.yaml) | Starter pack plus LibreOffice. | | [`winget/libre-soft-base-onlyoffice.yaml`](./winget/libre-soft-base-onlyoffice.yaml) | Starter pack plus ONLYOFFICE. | @@ -83,12 +83,14 @@ winget configure --file .\winget\libre-soft-start-pack.yaml --accept-configurati ## Remove Built-In Apps -Use the Appx cleanup script when you want to remove selected built-in applications without winget and prevent them from being provisioned for newly created users. +Use the Appx cleanup script when you want to remove selected built-in applications without winget and reduce reprovisioning for newly created users. ```powershell powershell -ExecutionPolicy Bypass -File .\powershell\Remove-BuiltInApps.ps1 ``` +The script removes installed and provisioned Appx packages, disables Microsoft consumer experiences, updates the default user profile `ContentDeliveryManager` settings and writes Appx deprovisioning registry markers. + OneDrive is not an Appx package on most Windows installations. To also call the built-in OneDrive uninstaller, pass `-IncludeOneDrive`: ```powershell @@ -101,7 +103,7 @@ The older winget-based cleanup script is still available, but it only targets th powershell -ExecutionPolicy Bypass -File .\powershell\Winget-Remove-BuiltInApps.ps1 ``` -Targeted applications include Xbox components, Outlook for Windows, Feedback Hub, Power Automate, Sticky Notes, Weather, Teams, Microsoft To Do, Bing apps, Clipchamp, Windows Web Experience Pack and related built-in packages. +Run this script before creating the new Windows user profile, then restart Windows. Targeted applications include Xbox components, Outlook for Windows, Feedback Hub, Power Automate, Sticky Notes, Weather, Teams, Microsoft To Do, Bing apps, Clipchamp, Windows Web Experience Pack and related built-in packages. ## Maintenance Note diff --git a/powershell/Remove-BuiltInApps.ps1 b/powershell/Remove-BuiltInApps.ps1 index 7447eec..d55466a 100644 --- a/powershell/Remove-BuiltInApps.ps1 +++ b/powershell/Remove-BuiltInApps.ps1 @@ -3,7 +3,7 @@ # Installed packages are removed for existing users when supported. # Provisioned packages are removed so they are not installed for new users. -[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "High")] +[CmdletBinding(SupportsShouldProcess = $true)] param( [switch]$IncludeOneDrive ) @@ -41,12 +41,67 @@ $PackageNamePatterns = @( "Clipchamp.Clipchamp" ) +$KnownPackageFamilyNames = @( + "MicrosoftWindows.Client.WebExperience_cw5n1h2txyewy", + "Microsoft.OutlookForWindows_8wekyb3d8bbwe", + "Microsoft.WindowsFeedbackHub_8wekyb3d8bbwe", + "Microsoft.XboxApp_8wekyb3d8bbwe", + "Microsoft.GamingApp_8wekyb3d8bbwe", + "Microsoft.Xbox.TCUI_8wekyb3d8bbwe", + "Microsoft.XboxGameOverlay_8wekyb3d8bbwe", + "Microsoft.XboxGamingOverlay_8wekyb3d8bbwe", + "Microsoft.XboxIdentityProvider_8wekyb3d8bbwe", + "Microsoft.XboxSpeechToTextOverlay_8wekyb3d8bbwe", + "Microsoft.PowerAutomateDesktop_8wekyb3d8bbwe", + "Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe", + "Microsoft.BingWeather_8wekyb3d8bbwe", + "MSTeams_8wekyb3d8bbwe", + "MicrosoftTeams_8wekyb3d8bbwe", + "Microsoft.Todos_8wekyb3d8bbwe", + "Microsoft.BingSearch_8wekyb3d8bbwe", + "Microsoft.BingNews_8wekyb3d8bbwe", + "Clipchamp.Clipchamp_yxz26nhyzhsrt" +) + +$Script:PackageFamilyNamesToBlock = @() + +function Add-PackageFamilyNameToBlockList { + param( + [string]$PackageFamilyName + ) + + if ([string]::IsNullOrWhiteSpace($PackageFamilyName)) { + return + } + + if ($Script:PackageFamilyNamesToBlock -notcontains $PackageFamilyName) { + $Script:PackageFamilyNamesToBlock += $PackageFamilyName + } +} + +function Get-PackageFamilyNameFromProvisionedPackage { + param( + [Parameter(Mandatory = $true)] + $Package + ) + + $Parts = $Package.PackageName -split "_" + + if ($Parts.Count -lt 2) { + return $null + } + + $PublisherId = $Parts[-1] + return "$($Package.DisplayName)_$PublisherId" +} + function Invoke-InstalledAppxPackageRemoval { param( [string]$Pattern ) - $Packages = Get-AppxPackage -AllUsers -Name $Pattern -ErrorAction SilentlyContinue + $Packages = Get-AppxPackage -AllUsers -ErrorAction SilentlyContinue | + Where-Object { $_.Name -like "*$Pattern*" -or $_.PackageFamilyName -like "*$Pattern*" } if (-not $Packages) { Write-Host "No installed Appx package found for: $Pattern" -ForegroundColor DarkGray @@ -54,6 +109,8 @@ function Invoke-InstalledAppxPackageRemoval { } foreach ($Package in $Packages) { + Add-PackageFamilyNameToBlockList -PackageFamilyName $Package.PackageFamilyName + $Target = "$($Package.Name) [$($Package.PackageFullName)]" Write-Host "Removing installed package: $Target" -ForegroundColor Cyan @@ -76,8 +133,8 @@ function Invoke-ProvisionedAppxPackageRemoval { $ProvisionedPackages = Get-AppxProvisionedPackage -Online | Where-Object { - $_.DisplayName -like $Pattern -or - $_.PackageName -like "$Pattern*" + $_.DisplayName -like "*$Pattern*" -or + $_.PackageName -like "*$Pattern*" } if (-not $ProvisionedPackages) { @@ -86,6 +143,8 @@ function Invoke-ProvisionedAppxPackageRemoval { } foreach ($Package in $ProvisionedPackages) { + Add-PackageFamilyNameToBlockList -PackageFamilyName (Get-PackageFamilyNameFromProvisionedPackage -Package $Package) + $Target = "$($Package.DisplayName) [$($Package.PackageName)]" Write-Host "Removing provisioned package: $Target" -ForegroundColor Cyan @@ -101,6 +160,125 @@ function Invoke-ProvisionedAppxPackageRemoval { } } +function Set-DWordValue { + param( + [string]$Path, + [string]$Name, + [int]$Value + ) + + if (-not (Test-Path $Path)) { + New-Item -Path $Path -Force | Out-Null + } + + New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType DWord -Force | Out-Null +} + +function Set-ConsumerExperiencePolicies { + $CloudContentPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" + + Write-Host "Disabling Microsoft consumer experiences policy..." -ForegroundColor Cyan + + if ($PSCmdlet.ShouldProcess($CloudContentPath, "Set CloudContent policies")) { + Set-DWordValue -Path $CloudContentPath -Name "DisableWindowsConsumerFeatures" -Value 1 + Set-DWordValue -Path $CloudContentPath -Name "DisableCloudOptimizedContent" -Value 1 + Write-Host "Microsoft consumer experience policies configured." -ForegroundColor Green + } +} + +function Set-ContentDeliveryManagerDefaults { + param( + [string]$RegistryRoot + ) + + $ContentDeliveryPath = Join-Path $RegistryRoot "SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" + $ValuesToDisable = @( + "ContentDeliveryAllowed", + "FeatureManagementEnabled", + "OemPreInstalledAppsEnabled", + "PreInstalledAppsEnabled", + "PreInstalledAppsEverEnabled", + "SilentInstalledAppsEnabled", + "SubscribedContent-310093Enabled", + "SubscribedContent-338387Enabled", + "SubscribedContent-338388Enabled", + "SubscribedContent-338389Enabled", + "SubscribedContent-338393Enabled", + "SubscribedContent-353694Enabled", + "SubscribedContent-353696Enabled", + "SystemPaneSuggestionsEnabled" + ) + + Write-Host "Configuring ContentDeliveryManager defaults in: $RegistryRoot" -ForegroundColor Cyan + + if ($PSCmdlet.ShouldProcess($RegistryRoot, "Disable ContentDeliveryManager app suggestions")) { + foreach ($ValueName in $ValuesToDisable) { + Set-DWordValue -Path $ContentDeliveryPath -Name $ValueName -Value 0 + } + Write-Host "ContentDeliveryManager defaults configured." -ForegroundColor Green + } +} + +function Set-DefaultUserContentDeliveryManagerDefaults { + $DefaultUserHive = "Registry::HKEY_USERS\DefaultUser" + $DefaultUserDat = Join-Path $env:SystemDrive "Users\Default\NTUSER.DAT" + $HiveWasLoaded = $false + + if (-not (Test-Path $DefaultUserDat)) { + Write-Warning "Default user hive not found: $DefaultUserDat" + return + } + + if (-not (Test-Path $DefaultUserHive)) { + Write-Host "Loading default user registry hive..." -ForegroundColor Cyan + & reg.exe load "HKU\DefaultUser" $DefaultUserDat | Out-Null + + if ($LASTEXITCODE -ne 0) { + Write-Warning "Failed to load default user registry hive." + return + } + + $HiveWasLoaded = $true + } + + try { + Set-ContentDeliveryManagerDefaults -RegistryRoot $DefaultUserHive + } + finally { + if ($HiveWasLoaded) { + Write-Host "Unloading default user registry hive..." -ForegroundColor Cyan + & reg.exe unload "HKU\DefaultUser" | Out-Null + + if ($LASTEXITCODE -ne 0) { + Write-Warning "Failed to unload default user registry hive. Close registry tools and retry." + } + } + } +} + +function Set-AppxDeprovisionedRegistryMarkers { + param( + [string[]]$PackageFamilyNames + ) + + $DeprovisionedPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Deprovisioned" + $PolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Appx\RemoveDefaultMicrosoftStorePackages" + + if (-not $PackageFamilyNames) { + return + } + + Write-Host "Writing Appx deprovisioning registry markers..." -ForegroundColor Cyan + + foreach ($PackageFamilyName in ($PackageFamilyNames | Sort-Object -Unique)) { + if ($PSCmdlet.ShouldProcess($PackageFamilyName, "Block Appx provisioning for future users")) { + New-Item -Path (Join-Path $DeprovisionedPath $PackageFamilyName) -Force | Out-Null + Set-DWordValue -Path (Join-Path $PolicyPath $PackageFamilyName) -Name "RemovePackage" -Value 1 + Write-Host "Blocked future provisioning: $PackageFamilyName" -ForegroundColor Green + } + } +} + function Invoke-OneDriveRemoval { $Installers = @( "$env:SystemRoot\System32\OneDriveSetup.exe", @@ -130,12 +308,22 @@ Write-Host "Removing selected built-in Appx applications..." -ForegroundColor Cy Write-Host "This can affect existing users and the default package set for new users." -ForegroundColor Yellow Write-Host "" +foreach ($PackageFamilyName in $KnownPackageFamilyNames) { + Add-PackageFamilyNameToBlockList -PackageFamilyName $PackageFamilyName +} + +Set-ConsumerExperiencePolicies +Set-ContentDeliveryManagerDefaults -RegistryRoot "HKCU:" +Set-DefaultUserContentDeliveryManagerDefaults + foreach ($Pattern in $PackageNamePatterns) { Invoke-InstalledAppxPackageRemoval -Pattern $Pattern Invoke-ProvisionedAppxPackageRemoval -Pattern $Pattern Write-Host "" } +Set-AppxDeprovisionedRegistryMarkers -PackageFamilyNames $Script:PackageFamilyNamesToBlock + if ($IncludeOneDrive) { Invoke-OneDriveRemoval }