Block built-in app reprovisioning

This commit is contained in:
2026-05-24 09:23:49 +02:00
parent a314e7a3a1
commit 12c7b375ff
3 changed files with 202 additions and 10 deletions
+192 -4
View File
@@ -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
}