noid-privacy/Modules/Privacy/Private/Set-PolicyBasedAppRemoval.ps1

118 lines
5.1 KiB
PowerShell
Raw Normal View History

function Set-PolicyBasedAppRemoval {
<#
.SYNOPSIS
Configure policy-based inbox app removal for Windows 11 25H2+ Enterprise/Education
.DESCRIPTION
Uses Microsoft's official RemoveDefaultMicrosoftStorePackages policy to remove
preinstalled apps at the policy level. This is the recommended method for Win11 25H2+.
Registry structure:
HKLM\SOFTWARE\Policies\Microsoft\Windows\Appx\RemoveDefaultMicrosoftStorePackages
Enabled = 1 (DWORD)
<AppID> (subkey)
RemovedPackage = 1 (DWORD)
.EXAMPLE
Set-PolicyBasedAppRemoval
.NOTES
Requires Windows 11 25H2+ Enterprise or Education edition
Apps are removed at next sign-in or OOBE
While policy is active, removed apps cannot be reinstalled
#>
[CmdletBinding()]
param()
try {
Write-Log -Level INFO -Message "Configuring policy-based inbox app removal..." -Module "Privacy"
# Load configuration
$configPath = Join-Path $PSScriptRoot "..\Config\Bloatware.json"
$config = Get-Content $configPath -Raw | ConvertFrom-Json
$policyMethod = $config.PolicyMethod
$policyConfiguredApps = @() # Track apps configured for removal
$registryPath = $policyMethod.RegistryPath
# Create root policy key if not exists
if (!(Test-Path $registryPath)) {
New-Item -Path $registryPath -Force | Out-Null
Write-Log -Level INFO -Message "Created policy key: $registryPath" -Module "Privacy"
}
# Enable the policy
$existing = Get-ItemProperty -Path $registryPath -Name "Enabled" -ErrorAction SilentlyContinue
if ($null -ne $existing) {
Set-ItemProperty -Path $registryPath -Name "Enabled" -Value 1 -Force | Out-Null
} else {
New-ItemProperty -Path $registryPath -Name "Enabled" -Value 1 -PropertyType DWord -Force | Out-Null
}
Write-Log -Level SUCCESS -Message "Policy enabled: RemoveDefaultMicrosoftStorePackages" -Module "Privacy"
# Configure each app
$appsToRemove = @()
foreach ($appId in $policyMethod.Apps.PSObject.Properties.Name) {
$shouldRemove = $policyMethod.Apps.$appId
if ($shouldRemove) {
# Create subkey for app
$appKeyPath = Join-Path $registryPath $appId
if (!(Test-Path $appKeyPath)) {
New-Item -Path $appKeyPath -Force | Out-Null
}
# Set RemovedPackage flag
$existing = Get-ItemProperty -Path $appKeyPath -Name "RemovedPackage" -ErrorAction SilentlyContinue
if ($null -ne $existing) {
Set-ItemProperty -Path $appKeyPath -Name "RemovedPackage" -Value 1 -Force | Out-Null
} else {
New-ItemProperty -Path $appKeyPath -Name "RemovedPackage" -Value 1 -PropertyType DWord -Force | Out-Null
}
$packageName = $policyMethod.AppMapping.$appId
Write-Log -Level SUCCESS -Message "Marked for removal: $appId ($packageName)" -Module "Privacy"
$appsToRemove += $appId
$policyConfiguredApps += $packageName # Track readable app name
} else {
# Ensure app is NOT marked for removal (defensive)
$appKeyPath = Join-Path $registryPath $appId
if (Test-Path $appKeyPath) {
Remove-Item -Path $appKeyPath -Recurse -Force
Write-Log -Level INFO -Message "Ensured NOT removed: $appId" -Module "Privacy"
}
}
}
Write-Host "`n============================================" -ForegroundColor Cyan
Write-Host " POLICY-BASED APP REMOVAL CONFIGURED" -ForegroundColor Cyan
Write-Host "============================================" -ForegroundColor Cyan
Write-Host "`nApps marked for removal: $($appsToRemove.Count)" -ForegroundColor Green
foreach ($app in $appsToRemove) {
Write-Host " - $app" -ForegroundColor Gray
}
Write-Host "`nNOTE: Apps will be removed at:" -ForegroundColor Yellow
Write-Host " - Next user sign-in" -ForegroundColor Gray
Write-Host " - OOBE (new device setup)" -ForegroundColor Gray
Write-Host " - After OS upgrade" -ForegroundColor Gray
Write-Host "`nWhile policy is active, removed apps CANNOT be reinstalled.`n" -ForegroundColor Yellow
Write-Log -Level SUCCESS -Message "Policy-based app removal configured successfully" -Module "Privacy"
# Return list of configured apps for user info
return [PSCustomObject]@{
Success = $true
RemovedApps = $policyConfiguredApps
Count = $appsToRemove.Count
}
} catch {
Write-Log -Level ERROR -Message "Failed to configure policy-based app removal: $_" -Module "Privacy"
return [PSCustomObject]@{
Success = $false
RemovedApps = @()
Count = 0
}
}
}