From 28d2b307b40fb1ea4fcfd654548ad27eca9be11b Mon Sep 17 00:00:00 2001 From: Mark Cornmesser Date: Mon, 2 Mar 2026 19:31:12 -0800 Subject: [PATCH 1/9] Fix - Bug 2013985 - Ensure HVEC is there before dsiable MS store features --- .../win_uninstall_appx_packages.ps1 | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/modules/win_disable_services/files/appxpackages/win_uninstall_appx_packages.ps1 b/modules/win_disable_services/files/appxpackages/win_uninstall_appx_packages.ps1 index f692f6d1d..dbf954185 100644 --- a/modules/win_disable_services/files/appxpackages/win_uninstall_appx_packages.ps1 +++ b/modules/win_disable_services/files/appxpackages/win_uninstall_appx_packages.ps1 @@ -70,6 +70,92 @@ function Stop-TranscriptSafe { try { Stop-Transcript | Out-Null } catch { } } +function Test-HEVCCodecPresent { + [CmdletBinding()] + param() + + # Installed packages (any users) + try { + $installed = Get-AppxPackage -AllUsers -ErrorAction SilentlyContinue | + Where-Object { + $_.Name -like "*HEVC*" -or $_.PackageFamilyName -like "*HEVC*" + } + if ($installed) { return $true } + } catch { } + + # Provisioned packages (image-level) + try { + $prov = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue | + Where-Object { + $_.DisplayName -like "*HEVC*" -or $_.PackageName -like "*HEVC*" + } + if ($prov) { return $true } + } catch { } + + return $false +} + +function Ensure-HEVCCodec { + [CmdletBinding()] + param( + [int]$TimeoutSeconds = 600 + ) + + Write-Log -message "Ensure-HEVCCodec :: checking HEVC codec extension presence" -severity "DEBUG" + + if (Test-HEVCCodecPresent) { + Write-Log -message "Ensure-HEVCCodec :: HEVC appears present (installed/provisioned)" -severity "INFO" + return $true + } + + Write-Log -message "Ensure-HEVCCodec :: HEVC not detected; attempting install BEFORE Store/AppXSvc changes" -severity "WARN" + + # Be kind to the Store/AppX stack before attempting install + Wait-AppxIdle -TimeoutSeconds 600 -SleepSeconds 15 | Out-Null + + # We prefer "from Device Manufacturer" (often free) first, then the standard HEVC package. + # winget IDs: + # 9N4WGH0Z6VHQ = HEVC Video Extensions from Device Manufacturer + # 9NMZLZ57R3T7 = HEVC Video Extensions + $candidates = @("9N4WGH0Z6VHQ", "9NMZLZ57R3T7") + + # Ensure winget is present + $winget = Get-Command winget.exe -ErrorAction SilentlyContinue + if (-not $winget) { + Write-Log -message "Ensure-HEVCCodec :: winget.exe not found; cannot install from Microsoft Store. (Consider keeping DesktopAppInstaller or provisioning HEVC offline.)" -severity "ERROR" + return $false + } + + foreach ($id in $candidates) { + Write-Log -message "Ensure-HEVCCodec :: attempting winget install: $id" -severity "INFO" + + $ok = Invoke-WithTimeout -TimeoutSeconds $TimeoutSeconds -ScriptBlock ([scriptblock]::Create(@" +`$ErrorActionPreference = 'Continue' +try { + # -h = hidden (no UI), best-effort for CI + & winget.exe install $id --source msstore --accept-package-agreements --accept-source-agreements -h +} catch { } +"@)) + + # Give AppX a moment to settle then re-check + Wait-AppxIdle -TimeoutSeconds 600 -SleepSeconds 15 | Out-Null + + if (Test-HEVCCodecPresent) { + Write-Log -message "Ensure-HEVCCodec :: HEVC detected after install attempt ($id)" -severity "INFO" + return $true + } + + if (-not $ok) { + Write-Log -message "Ensure-HEVCCodec :: winget attempt timed out for $id" -severity "WARN" + } else { + Write-Log -message "Ensure-HEVCCodec :: install attempt finished but HEVC still not detected for $id" -severity "WARN" + } + } + + Write-Log -message "Ensure-HEVCCodec :: failed to install HEVC via winget/msstore; proceeding (but HEVC mochitests may fail)" -severity "ERROR" + return $false +} + # Wait for likely-update activity to calm down (lightweight; does NOT depend on services being stopped) function Wait-AppxIdle { [CmdletBinding()] @@ -234,6 +320,9 @@ try { } # --- Main --------------------------------------------------------------- +## Ensure HEVC is aviable before we start uninstalling AppX packages +## https://bugzilla.mozilla.org/show_bug.cgi?id=2013985 +Ensure-HEVCCodec try { Write-Log -message 'uninstall_appx_packages :: begin' -severity 'DEBUG' From 182bdd8252c1a33d86764dbfa502c298f9f3507b Mon Sep 17 00:00:00 2001 From: Mark Cornmesser Date: Mon, 2 Mar 2026 21:08:26 -0800 Subject: [PATCH 2/9] Fix - Bug 2013985 - Ensure HVEC is there before dsiable MS store features --- .../files/appxpackages/hw-uninstall.ps1 | 89 ++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 b/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 index 1b8ff2767..506f8667e 100644 --- a/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 +++ b/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 @@ -188,7 +188,7 @@ function Remove-PreinstalledAppxPackages { "Microsoft.WindowsStore" = @{ VDIState="Unchanged"; URL="https://blogs.windows.com/windowsexperience/2021/06/24/building-a-new-open-microsoft-store-on-windows-11/"; Description="Microsoft Store" } "Microsoft.WindowsSoundRecorder" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-voice-recorder/9wzdncrfhwkn"; Description="Voice Recorder" } #"Microsoft.WindowsTerminal" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701"; Description="Windows Terminal" } - "Microsoft.Winget.Platform.Source"= @{ VDIState="Unchanged"; URL="https://learn.microsoft.com/en-us/windows/package-manager/winget/"; Description="Winget source" } + #"Microsoft.Winget.Platform.Source"= @{ VDIState="Unchanged"; URL="https://learn.microsoft.com/en-us/windows/package-manager/winget/"; Description="Winget source" } "Microsoft.Xbox.TCUI" = @{ VDIState="Unchanged"; URL="https://docs.microsoft.com/en-us/gaming/xbox-live/features/general/tcui/live-tcui-overview"; Description="Xbox TCUI" } "Microsoft.XboxIdentityProvider" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/xbox-identity-provider/9wzdncrd1hkw"; Description="Xbox Identity Provider" } "Microsoft.XboxSpeechToTextOverlay" = @{ VDIState="Unchanged"; URL="https://support.xbox.com/help/account-profile/accessibility/use-game-chat-transcription"; Description="Xbox chat transcription" } @@ -358,10 +358,97 @@ function Test-AppXSvcDisabled { if ($svc.Status -eq 'Stopped' -and ($regDisabled -or $cimDisabled)) { return $true } return $false } +function Test-HEVCCodecPresent { + [CmdletBinding()] + param() + + # Installed packages (any users) + try { + $installed = Get-AppxPackage -AllUsers -ErrorAction SilentlyContinue | + Where-Object { + $_.Name -like "*HEVC*" -or $_.PackageFamilyName -like "*HEVC*" + } + if ($installed) { return $true } + } catch { } + + # Provisioned packages (image-level) + try { + $prov = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue | + Where-Object { + $_.DisplayName -like "*HEVC*" -or $_.PackageName -like "*HEVC*" + } + if ($prov) { return $true } + } catch { } + + return $false +} + +function Ensure-HEVCCodec { + [CmdletBinding()] + param( + [int]$TimeoutSeconds = 600 + ) + + Write-Log -message "Ensure-HEVCCodec :: checking HEVC codec extension presence" -severity "DEBUG" + + if (Test-HEVCCodecPresent) { + Write-Log -message "Ensure-HEVCCodec :: HEVC appears present (installed/provisioned)" -severity "INFO" + return $true + } + + Write-Log -message "Ensure-HEVCCodec :: HEVC not detected; attempting install BEFORE Store/AppXSvc changes" -severity "WARN" + # Be kind to the Store/AppX stack before attempting install + Wait-AppxIdle -TimeoutSeconds 600 -SleepSeconds 15 | Out-Null + + # We prefer "from Device Manufacturer" (often free) first, then the standard HEVC package. + # winget IDs: + # 9N4WGH0Z6VHQ = HEVC Video Extensions from Device Manufacturer + # 9NMZLZ57R3T7 = HEVC Video Extensions + $candidates = @("9N4WGH0Z6VHQ", "9NMZLZ57R3T7") + + # Ensure winget is present + $winget = Get-Command winget.exe -ErrorAction SilentlyContinue + if (-not $winget) { + Write-Log -message "Ensure-HEVCCodec :: winget.exe not found; cannot install from Microsoft Store. (Consider keeping DesktopAppInstaller or provisioning HEVC offline.)" -severity "ERROR" + return $false + } + + foreach ($id in $candidates) { + Write-Log -message "Ensure-HEVCCodec :: attempting winget install: $id" -severity "INFO" + + $ok = Invoke-WithTimeout -TimeoutSeconds $TimeoutSeconds -ScriptBlock ([scriptblock]::Create(@" +`$ErrorActionPreference = 'Continue' +try { + # -h = hidden (no UI), best-effort for CI + & winget.exe install $id --source msstore --accept-package-agreements --accept-source-agreements -h +} catch { } +"@)) + + # Give AppX a moment to settle then re-check + Wait-AppxIdle -TimeoutSeconds 600 -SleepSeconds 15 | Out-Null + + if (Test-HEVCCodecPresent) { + Write-Log -message "Ensure-HEVCCodec :: HEVC detected after install attempt ($id)" -severity "INFO" + return $true + } + + if (-not $ok) { + Write-Log -message "Ensure-HEVCCodec :: winget attempt timed out for $id" -severity "WARN" + } else { + Write-Log -message "Ensure-HEVCCodec :: install attempt finished but HEVC still not detected for $id" -severity "WARN" + } + } + + Write-Log -message "Ensure-HEVCCodec :: failed to install HEVC via winget/msstore; proceeding (but HEVC mochitests may fail)" -severity "ERROR" + return $false +} # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- +## Ensure HEVC is aviable before we start uninstalling AppX packages +## https://bugzilla.mozilla.org/show_bug.cgi?id=2013985 +Ensure-HEVCCodec try { Write-Log -message 'uninstall_appx_packages :: begin' -severity 'DEBUG' From 25a0ab014ed34c5d93d2fb9a60932d41bf551d54 Mon Sep 17 00:00:00 2001 From: Mark Cornmesser Date: Tue, 3 Mar 2026 08:29:14 -0800 Subject: [PATCH 3/9] revert scripts --- .../files/appxpackages/hw-uninstall.ps1 | 89 +------------------ .../win_uninstall_appx_packages.ps1 | 89 ------------------- 2 files changed, 1 insertion(+), 177 deletions(-) diff --git a/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 b/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 index 506f8667e..1b8ff2767 100644 --- a/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 +++ b/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 @@ -188,7 +188,7 @@ function Remove-PreinstalledAppxPackages { "Microsoft.WindowsStore" = @{ VDIState="Unchanged"; URL="https://blogs.windows.com/windowsexperience/2021/06/24/building-a-new-open-microsoft-store-on-windows-11/"; Description="Microsoft Store" } "Microsoft.WindowsSoundRecorder" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-voice-recorder/9wzdncrfhwkn"; Description="Voice Recorder" } #"Microsoft.WindowsTerminal" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701"; Description="Windows Terminal" } - #"Microsoft.Winget.Platform.Source"= @{ VDIState="Unchanged"; URL="https://learn.microsoft.com/en-us/windows/package-manager/winget/"; Description="Winget source" } + "Microsoft.Winget.Platform.Source"= @{ VDIState="Unchanged"; URL="https://learn.microsoft.com/en-us/windows/package-manager/winget/"; Description="Winget source" } "Microsoft.Xbox.TCUI" = @{ VDIState="Unchanged"; URL="https://docs.microsoft.com/en-us/gaming/xbox-live/features/general/tcui/live-tcui-overview"; Description="Xbox TCUI" } "Microsoft.XboxIdentityProvider" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/xbox-identity-provider/9wzdncrd1hkw"; Description="Xbox Identity Provider" } "Microsoft.XboxSpeechToTextOverlay" = @{ VDIState="Unchanged"; URL="https://support.xbox.com/help/account-profile/accessibility/use-game-chat-transcription"; Description="Xbox chat transcription" } @@ -358,97 +358,10 @@ function Test-AppXSvcDisabled { if ($svc.Status -eq 'Stopped' -and ($regDisabled -or $cimDisabled)) { return $true } return $false } -function Test-HEVCCodecPresent { - [CmdletBinding()] - param() - - # Installed packages (any users) - try { - $installed = Get-AppxPackage -AllUsers -ErrorAction SilentlyContinue | - Where-Object { - $_.Name -like "*HEVC*" -or $_.PackageFamilyName -like "*HEVC*" - } - if ($installed) { return $true } - } catch { } - - # Provisioned packages (image-level) - try { - $prov = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue | - Where-Object { - $_.DisplayName -like "*HEVC*" -or $_.PackageName -like "*HEVC*" - } - if ($prov) { return $true } - } catch { } - - return $false -} - -function Ensure-HEVCCodec { - [CmdletBinding()] - param( - [int]$TimeoutSeconds = 600 - ) - - Write-Log -message "Ensure-HEVCCodec :: checking HEVC codec extension presence" -severity "DEBUG" - - if (Test-HEVCCodecPresent) { - Write-Log -message "Ensure-HEVCCodec :: HEVC appears present (installed/provisioned)" -severity "INFO" - return $true - } - - Write-Log -message "Ensure-HEVCCodec :: HEVC not detected; attempting install BEFORE Store/AppXSvc changes" -severity "WARN" - # Be kind to the Store/AppX stack before attempting install - Wait-AppxIdle -TimeoutSeconds 600 -SleepSeconds 15 | Out-Null - - # We prefer "from Device Manufacturer" (often free) first, then the standard HEVC package. - # winget IDs: - # 9N4WGH0Z6VHQ = HEVC Video Extensions from Device Manufacturer - # 9NMZLZ57R3T7 = HEVC Video Extensions - $candidates = @("9N4WGH0Z6VHQ", "9NMZLZ57R3T7") - - # Ensure winget is present - $winget = Get-Command winget.exe -ErrorAction SilentlyContinue - if (-not $winget) { - Write-Log -message "Ensure-HEVCCodec :: winget.exe not found; cannot install from Microsoft Store. (Consider keeping DesktopAppInstaller or provisioning HEVC offline.)" -severity "ERROR" - return $false - } - - foreach ($id in $candidates) { - Write-Log -message "Ensure-HEVCCodec :: attempting winget install: $id" -severity "INFO" - - $ok = Invoke-WithTimeout -TimeoutSeconds $TimeoutSeconds -ScriptBlock ([scriptblock]::Create(@" -`$ErrorActionPreference = 'Continue' -try { - # -h = hidden (no UI), best-effort for CI - & winget.exe install $id --source msstore --accept-package-agreements --accept-source-agreements -h -} catch { } -"@)) - - # Give AppX a moment to settle then re-check - Wait-AppxIdle -TimeoutSeconds 600 -SleepSeconds 15 | Out-Null - - if (Test-HEVCCodecPresent) { - Write-Log -message "Ensure-HEVCCodec :: HEVC detected after install attempt ($id)" -severity "INFO" - return $true - } - - if (-not $ok) { - Write-Log -message "Ensure-HEVCCodec :: winget attempt timed out for $id" -severity "WARN" - } else { - Write-Log -message "Ensure-HEVCCodec :: install attempt finished but HEVC still not detected for $id" -severity "WARN" - } - } - - Write-Log -message "Ensure-HEVCCodec :: failed to install HEVC via winget/msstore; proceeding (but HEVC mochitests may fail)" -severity "ERROR" - return $false -} # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- -## Ensure HEVC is aviable before we start uninstalling AppX packages -## https://bugzilla.mozilla.org/show_bug.cgi?id=2013985 -Ensure-HEVCCodec try { Write-Log -message 'uninstall_appx_packages :: begin' -severity 'DEBUG' diff --git a/modules/win_disable_services/files/appxpackages/win_uninstall_appx_packages.ps1 b/modules/win_disable_services/files/appxpackages/win_uninstall_appx_packages.ps1 index dbf954185..f692f6d1d 100644 --- a/modules/win_disable_services/files/appxpackages/win_uninstall_appx_packages.ps1 +++ b/modules/win_disable_services/files/appxpackages/win_uninstall_appx_packages.ps1 @@ -70,92 +70,6 @@ function Stop-TranscriptSafe { try { Stop-Transcript | Out-Null } catch { } } -function Test-HEVCCodecPresent { - [CmdletBinding()] - param() - - # Installed packages (any users) - try { - $installed = Get-AppxPackage -AllUsers -ErrorAction SilentlyContinue | - Where-Object { - $_.Name -like "*HEVC*" -or $_.PackageFamilyName -like "*HEVC*" - } - if ($installed) { return $true } - } catch { } - - # Provisioned packages (image-level) - try { - $prov = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue | - Where-Object { - $_.DisplayName -like "*HEVC*" -or $_.PackageName -like "*HEVC*" - } - if ($prov) { return $true } - } catch { } - - return $false -} - -function Ensure-HEVCCodec { - [CmdletBinding()] - param( - [int]$TimeoutSeconds = 600 - ) - - Write-Log -message "Ensure-HEVCCodec :: checking HEVC codec extension presence" -severity "DEBUG" - - if (Test-HEVCCodecPresent) { - Write-Log -message "Ensure-HEVCCodec :: HEVC appears present (installed/provisioned)" -severity "INFO" - return $true - } - - Write-Log -message "Ensure-HEVCCodec :: HEVC not detected; attempting install BEFORE Store/AppXSvc changes" -severity "WARN" - - # Be kind to the Store/AppX stack before attempting install - Wait-AppxIdle -TimeoutSeconds 600 -SleepSeconds 15 | Out-Null - - # We prefer "from Device Manufacturer" (often free) first, then the standard HEVC package. - # winget IDs: - # 9N4WGH0Z6VHQ = HEVC Video Extensions from Device Manufacturer - # 9NMZLZ57R3T7 = HEVC Video Extensions - $candidates = @("9N4WGH0Z6VHQ", "9NMZLZ57R3T7") - - # Ensure winget is present - $winget = Get-Command winget.exe -ErrorAction SilentlyContinue - if (-not $winget) { - Write-Log -message "Ensure-HEVCCodec :: winget.exe not found; cannot install from Microsoft Store. (Consider keeping DesktopAppInstaller or provisioning HEVC offline.)" -severity "ERROR" - return $false - } - - foreach ($id in $candidates) { - Write-Log -message "Ensure-HEVCCodec :: attempting winget install: $id" -severity "INFO" - - $ok = Invoke-WithTimeout -TimeoutSeconds $TimeoutSeconds -ScriptBlock ([scriptblock]::Create(@" -`$ErrorActionPreference = 'Continue' -try { - # -h = hidden (no UI), best-effort for CI - & winget.exe install $id --source msstore --accept-package-agreements --accept-source-agreements -h -} catch { } -"@)) - - # Give AppX a moment to settle then re-check - Wait-AppxIdle -TimeoutSeconds 600 -SleepSeconds 15 | Out-Null - - if (Test-HEVCCodecPresent) { - Write-Log -message "Ensure-HEVCCodec :: HEVC detected after install attempt ($id)" -severity "INFO" - return $true - } - - if (-not $ok) { - Write-Log -message "Ensure-HEVCCodec :: winget attempt timed out for $id" -severity "WARN" - } else { - Write-Log -message "Ensure-HEVCCodec :: install attempt finished but HEVC still not detected for $id" -severity "WARN" - } - } - - Write-Log -message "Ensure-HEVCCodec :: failed to install HEVC via winget/msstore; proceeding (but HEVC mochitests may fail)" -severity "ERROR" - return $false -} - # Wait for likely-update activity to calm down (lightweight; does NOT depend on services being stopped) function Wait-AppxIdle { [CmdletBinding()] @@ -320,9 +234,6 @@ try { } # --- Main --------------------------------------------------------------- -## Ensure HEVC is aviable before we start uninstalling AppX packages -## https://bugzilla.mozilla.org/show_bug.cgi?id=2013985 -Ensure-HEVCCodec try { Write-Log -message 'uninstall_appx_packages :: begin' -severity 'DEBUG' From cbc0f531367664aba80dd403a897be9cfff29590 Mon Sep 17 00:00:00 2001 From: Mark Cornmesser Date: Tue, 3 Mar 2026 08:35:41 -0800 Subject: [PATCH 4/9] don't remove APPX packegs for ref workers --- .../roles_profiles/manifests/profiles/disable_services.pp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/roles_profiles/manifests/profiles/disable_services.pp b/modules/roles_profiles/manifests/profiles/disable_services.pp index 139782a8d..9bc656e21 100644 --- a/modules/roles_profiles/manifests/profiles/disable_services.pp +++ b/modules/roles_profiles/manifests/profiles/disable_services.pp @@ -49,8 +49,10 @@ } case $facts['custom_win_location'] { 'datacenter': { - $apx_uninstall = 'hw-uninstall.ps1' - include win_disable_services::disable_optional_services + if $facts['custom_win_worker_pool_id'] !~ /ref/ { + $apx_uninstall = 'hw-uninstall.ps1' + include win_disable_services::disable_optional_services + } } 'azure': { $apx_uninstall = 'uninstall.ps1' From 0485d5edc79e181fbd67f36c238fd2b8600317a7 Mon Sep 17 00:00:00 2001 From: Mark Cornmesser Date: Tue, 3 Mar 2026 10:10:36 -0800 Subject: [PATCH 5/9] don't remove APPX packegs for ref workers --- modules/roles_profiles/manifests/profiles/disable_services.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/roles_profiles/manifests/profiles/disable_services.pp b/modules/roles_profiles/manifests/profiles/disable_services.pp index 9bc656e21..b9a2cc558 100644 --- a/modules/roles_profiles/manifests/profiles/disable_services.pp +++ b/modules/roles_profiles/manifests/profiles/disable_services.pp @@ -49,7 +49,7 @@ } case $facts['custom_win_location'] { 'datacenter': { - if $facts['custom_win_worker_pool_id'] !~ /ref/ { + if !('ref' in $facts['custom_win_worker_pool_id']) { $apx_uninstall = 'hw-uninstall.ps1' include win_disable_services::disable_optional_services } From 44962a9712f7e8cb1bacd27929ccc585d3d0ad70 Mon Sep 17 00:00:00 2001 From: Mark Cornmesser Date: Tue, 3 Mar 2026 10:52:17 -0800 Subject: [PATCH 6/9] don't remove APPX packegs for ref workers --- modules/roles_profiles/manifests/profiles/disable_services.pp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/roles_profiles/manifests/profiles/disable_services.pp b/modules/roles_profiles/manifests/profiles/disable_services.pp index b9a2cc558..991fa8ade 100644 --- a/modules/roles_profiles/manifests/profiles/disable_services.pp +++ b/modules/roles_profiles/manifests/profiles/disable_services.pp @@ -49,7 +49,8 @@ } case $facts['custom_win_location'] { 'datacenter': { - if !('ref' in $facts['custom_win_worker_pool_id']) { + $ref_pools = ['win11-64-24h2-hw-ref-alpha', 'win11-64-24h2-hw-ref'] + if !($facts['custom_win_worker_pool_id'] in $ref_pools) { $apx_uninstall = 'hw-uninstall.ps1' include win_disable_services::disable_optional_services } From c39b60ea16045607e619eb58f9a42d01f4656af9 Mon Sep 17 00:00:00 2001 From: Mark Cornmesser Date: Tue, 3 Mar 2026 11:28:12 -0800 Subject: [PATCH 7/9] don't remove APPX packegs for ref workers --- .../manifests/profiles/disable_services.pp | 6 ++--- .../files/appxpackages/hw-uninstall.ps1 | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/modules/roles_profiles/manifests/profiles/disable_services.pp b/modules/roles_profiles/manifests/profiles/disable_services.pp index 991fa8ade..572c501f8 100644 --- a/modules/roles_profiles/manifests/profiles/disable_services.pp +++ b/modules/roles_profiles/manifests/profiles/disable_services.pp @@ -50,10 +50,8 @@ case $facts['custom_win_location'] { 'datacenter': { $ref_pools = ['win11-64-24h2-hw-ref-alpha', 'win11-64-24h2-hw-ref'] - if !($facts['custom_win_worker_pool_id'] in $ref_pools) { - $apx_uninstall = 'hw-uninstall.ps1' - include win_disable_services::disable_optional_services - } + $apx_uninstall = 'hw-uninstall.ps1' + include win_disable_services::disable_optional_services } 'azure': { $apx_uninstall = 'uninstall.ps1' diff --git a/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 b/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 index 1b8ff2767..559295a4f 100644 --- a/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 +++ b/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 @@ -358,7 +358,32 @@ function Test-AppXSvcDisabled { if ($svc.Status -eq 'Stopped' -and ($regDisabled -or $cimDisabled)) { return $true } return $false } +# --------------------------------------------------------------------------- +# Skip AppX uninstall for ref pools +# --------------------------------------------------------------------------- +try { + $rpKey = 'HKLM:\SOFTWARE\Mozilla\ronin_puppet' + $wpId = (Get-ItemProperty -Path $rpKey -Name 'worker_pool_id' -ErrorAction Stop).worker_pool_id + $skipNeedles = @( + 'win11-64-24h2-hw-ref-alpha', + 'win11-64-24h2-hw-ref' + ) + + foreach ($needle in $skipNeedles) { + if ($wpId -like "*$needle*") { + Write-Log -message "uninstall_appx_packages :: SKIP: worker_pool_id='$wpId' matched '$needle' (ref pool). Exiting 0." -severity 'INFO' + Stop-TranscriptSafe + exit 0 + } + } + + Write-Log -message "uninstall_appx_packages :: worker_pool_id='$wpId' did not match ref pools; continuing." -severity 'DEBUG' +} +catch { + # If you *never* want this to block the run, log and continue. + Write-Log -message "uninstall_appx_packages :: WARN: could not read worker_pool_id from registry ($($_.Exception.Message)); continuing." -severity 'WARN' +} # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- From 837e3b42dcd0f20178a7d573dd87fd6b7bd61cfa Mon Sep 17 00:00:00 2001 From: Mark Cornmesser Date: Tue, 3 Mar 2026 12:10:58 -0800 Subject: [PATCH 8/9] don't remove APPX packegs for ref workers --- .../roles_profiles/manifests/profiles/disable_services.pp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/roles_profiles/manifests/profiles/disable_services.pp b/modules/roles_profiles/manifests/profiles/disable_services.pp index 572c501f8..cbc39e155 100644 --- a/modules/roles_profiles/manifests/profiles/disable_services.pp +++ b/modules/roles_profiles/manifests/profiles/disable_services.pp @@ -49,8 +49,6 @@ } case $facts['custom_win_location'] { 'datacenter': { - $ref_pools = ['win11-64-24h2-hw-ref-alpha', 'win11-64-24h2-hw-ref'] - $apx_uninstall = 'hw-uninstall.ps1' include win_disable_services::disable_optional_services } 'azure': { @@ -73,7 +71,10 @@ ## must be ran after apx uninstall if ($facts['custom_win_location'] == 'datacenter') { include win_disable_services::disable_ms_edge - include win_disable_services::extended_uninstall_appx_packages + if $facts['custom_win_worker_pool_id'] != 'win11-64-24h2-hw-ref-alpha' and + $facts['custom_win_worker_pool_id'] != 'win11-64-24h2-hw-ref' { + include win_disable_services::extended_uninstall_appx_packages + } } } # May be needed for non-hardaware From 1599b8bacb4f4e60273640356e4a6293e379cc5d Mon Sep 17 00:00:00 2001 From: Mark Cornmesser Date: Tue, 3 Mar 2026 12:11:59 -0800 Subject: [PATCH 9/9] don't remove APPX packegs for ref workers --- .../files/appxpackages/hw-uninstall.ps1 | 447 ------------------ 1 file changed, 447 deletions(-) delete mode 100644 modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 diff --git a/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 b/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 deleted file mode 100644 index 559295a4f..000000000 --- a/modules/win_disable_services/files/appxpackages/hw-uninstall.ps1 +++ /dev/null @@ -1,447 +0,0 @@ -$Script:Version = "win_uninstall_appx_packages.ps1 2026-02-19 v4" -Write-Output "uninstall_appx_packages :: starting ($Script:Version)" - -function Write-Log { - param ( - [string] $message, - [ValidateSet('DEBUG','INFO','WARN','ERROR')] - [string] $severity = 'INFO', - [string] $source = 'BootStrap', - [string] $logName = 'Application' - ) - - $entryType = 'Information' - $eventId = 1 - - switch ($severity) { - 'DEBUG' { $entryType = 'SuccessAudit'; $eventId = 2; break } - 'WARN' { $entryType = 'Warning'; $eventId = 3; break } - 'ERROR' { $entryType = 'Error'; $eventId = 4; break } - default { $entryType = 'Information'; $eventId = 1; break } - } - - # Always emit to stdout so Puppet logoutput captures it - try { Write-Output $message } catch { } - - # Best-effort event log creation (avoid terminating failures / races) - try { - if (!([Diagnostics.EventLog]::Exists($logName)) -or - !([Diagnostics.EventLog]::SourceExists($source))) { - New-EventLog -LogName $logName -Source $source -ErrorAction SilentlyContinue | Out-Null - } - } catch { - # ignore - } - - try { - Write-EventLog -LogName $logName -Source $source ` - -EntryType $entryType -Category 0 -EventID $eventId ` - -Message $message -ErrorAction SilentlyContinue - } catch { - # ignore - } - - if ([Environment]::UserInteractive) { - $fc = @{ - 'Information' = 'White' - 'Error' = 'Red' - 'Warning' = 'DarkYellow' - 'SuccessAudit' = 'DarkGray' - }[$entryType] - Write-Host $message -ForegroundColor $fc - } -} - -# IMPORTANT: use 'Continue' so normal AppX noise doesn't hard-fail Puppet -$ErrorActionPreference = 'Continue' - -$svcName = 'AppXSvc' -$svcKeyPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\AppXSvc' - -# --------------------------------------------------------------------------- -# Optional transcript (works even if Puppet swallows stdout) -# --------------------------------------------------------------------------- -$Script:TranscriptPath = $null -try { - $logDir = "C:\ProgramData\PuppetLabs\ronin\logs" - if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null } - - $ts = Get-Date -Format "yyyyMMdd-HHmmss" - $Script:TranscriptPath = Join-Path $logDir "uninstall_appx_packages-$ts.log" - Start-Transcript -Path $Script:TranscriptPath -Force | Out-Null - Write-Log -message "uninstall_appx_packages :: transcript: $Script:TranscriptPath" -severity "DEBUG" -} catch { - # best-effort only -} - -function Stop-TranscriptSafe { - try { Stop-Transcript | Out-Null } catch { } -} - -# --------------------------------------------------------------------------- -# Wait for Store/AppX activity to calm down (helps avoid 0x80073D02 races) -# --------------------------------------------------------------------------- -function Wait-AppxIdle { - [CmdletBinding()] - param( - [int]$TimeoutSeconds = 600, - [int]$SleepSeconds = 15 - ) - - $deadline = (Get-Date).AddSeconds($TimeoutSeconds) - - while ((Get-Date) -lt $deadline) { - $busy = $false - - # Process signals that AppX/Store/Windows Update are active - $procNames = @( - "TiWorker", "TrustedInstaller", "MoUsoCoreWorker", "UsoClient", - "wsappx", "AppXSvc", "ClipSVC" - ) - - foreach ($p in $procNames) { - try { - if (Get-Process -Name $p -ErrorAction SilentlyContinue) { $busy = $true; break } - } catch { } - } - - # Service signal - try { - $wua = Get-Service wuauserv -ErrorAction SilentlyContinue - if ($wua -and $wua.Status -eq "Running") { $busy = $true } - } catch { } - - if (-not $busy) { - Write-Log -message "Wait-AppxIdle :: appears idle" -severity "DEBUG" - return $true - } - - Write-Log -message "Wait-AppxIdle :: busy (waiting $SleepSeconds s)" -severity "DEBUG" - Start-Sleep -Seconds $SleepSeconds - } - - Write-Log -message "Wait-AppxIdle :: timed out after $TimeoutSeconds seconds; proceeding anyway" -severity "WARN" - return $false -} - -# --------------------------------------------------------------------------- -# Run a block with a timeout so a single AppX call can’t hang the whole run -# --------------------------------------------------------------------------- -function Invoke-WithTimeout { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true)][scriptblock]$ScriptBlock, - [int]$TimeoutSeconds = 180 - ) - - $job = Start-Job -ScriptBlock $ScriptBlock - try { - if (Wait-Job $job -Timeout $TimeoutSeconds) { - Receive-Job $job -ErrorAction SilentlyContinue | Out-Null - return $true - } else { - try { Stop-Job $job -Force -ErrorAction SilentlyContinue | Out-Null } catch { } - Write-Log -message "Invoke-WithTimeout :: timed out after $TimeoutSeconds seconds" -severity "WARN" - return $false - } - } finally { - try { Remove-Job $job -Force -ErrorAction SilentlyContinue | Out-Null } catch { } - } -} - -function Remove-PreinstalledAppxPackages { - [CmdletBinding()] - param() - - $apps = @{ - "Bing Search" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/9nzbf4gt040c"; Description="Web Search from Microsoft Bing provides web results and answers in Windows Search" } - "Clipchamp.Clipchamp" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/9p1j8s7ccwwt?hl=en-us&gl=US"; Description="Create videos with a few clicks" } - "Microsoft.549981C3F5F10" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/cortana/9NFFX4SZZ23L?hl=en-us&gl=US"; Description="Cortana (could not update)" } - "Microsoft.BingNews" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/microsoft-news/9wzdncrfhvfw"; Description="Microsoft News app" } - "Microsoft.BingWeather" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/msn-weather/9wzdncrfj3q2"; Description="MSN Weather app" } - #"Microsoft.DesktopAppInstaller" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/9NBLGGH4NNS1"; Description="Microsoft App Installer for Windows 10 makes sideloading Windows apps easy" } - "Microsoft.GetHelp" = @{ VDIState="Unchanged"; URL="https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/customize-get-help-app"; Description="App that facilitates free support for Microsoft products" } - "Microsoft.Getstarted" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/microsoft-tips/9wzdncrdtbjj"; Description="Windows 10 tips app" } - "Microsoft.MicrosoftOfficeHub" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/office/9wzdncrd29v9"; Description="Office UWP app suite" } - "Microsoft.Office.OneNote" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/onenote-for-windows-10/9wzdncrfhvjl"; Description="Office UWP OneNote app" } - "Microsoft.MicrosoftSolitaireCollection" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/microsoft-solitaire-collection/9wzdncrfhwd2"; Description="Solitaire suite of games" } - "Microsoft.MicrosoftStickyNotes" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/microsoft-sticky-notes/9nblggh4qghw"; Description="Note-taking app" } - "Microsoft.OutlookForWindows" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/9NRX63209R7B?hl=en-us&gl=US"; Description="New Outlook app" } - "Microsoft.MSPaint" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/store/detail/paint-3d/9NBLGGH5FV99"; Description="Paint 3D app" } - "Microsoft.Paint" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/9PCFS5B6T72H"; Description="Classic Paint app" } - "Microsoft.People" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/microsoft-people/9nblggh10pg8"; Description="Contact management app" } - "Microsoft.PowerAutomateDesktop" = @{ VDIState="Unchanged"; URL="https://flow.microsoft.com/en-us/desktop/"; Description="Power Automate Desktop" } - "Microsoft.ScreenSketch" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/snip-sketch/9mz95kl8mr0l"; Description="Snip and Sketch app" } - "Microsoft.SkypeApp" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/skype/9wzdncrfj364"; Description="Skype app" } - "Microsoft.StorePurchaseApp" = @{ VDIState="Unchanged"; URL=""; Description="Store purchase app helper" } - "Microsoft.Todos" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/microsoft-to-do-lists-tasks-reminders/9nblggh5r558"; Description="Microsoft To Do" } - "Microsoft.WinDbg.Fast" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/9PGJGD53TN86?hl=en-us&gl=US"; Description="WinDbg" } - "Microsoft.Windows.DevHome" = @{ VDIState="Unchanged"; URL="https://learn.microsoft.com/en-us/windows/dev-home/"; Description="Dev Home dashboard" } - "Microsoft.Windows.Photos" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/microsoft-photos/9wzdncrfjbh4"; Description="Photos app" } - "Microsoft.WindowsAlarms" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-alarms-clock/9wzdncrfj3pr"; Description="Alarms & Clock" } - "Microsoft.WindowsCalculator" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-calculator/9wzdncrfhvn5"; Description="Calculator" } - "Microsoft.WindowsCamera" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-camera/9wzdncrfjbbg"; Description="Camera" } - "microsoft.windowscommunicationsapps" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/mail-and-calendar/9wzdncrfhvqm"; Description="Mail & Calendar" } - "Microsoft.WindowsFeedbackHub" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/feedback-hub/9nblggh4r32n"; Description="Feedback Hub" } - "Microsoft.WindowsMaps" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-maps/9wzdncrdtbvb"; Description="Maps" } - "Microsoft.WindowsNotepad" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-notepad/9msmlrh6lzf3"; Description="Notepad (Store)" } - "Microsoft.WindowsStore" = @{ VDIState="Unchanged"; URL="https://blogs.windows.com/windowsexperience/2021/06/24/building-a-new-open-microsoft-store-on-windows-11/"; Description="Microsoft Store" } - "Microsoft.WindowsSoundRecorder" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-voice-recorder/9wzdncrfhwkn"; Description="Voice Recorder" } - #"Microsoft.WindowsTerminal" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701"; Description="Windows Terminal" } - "Microsoft.Winget.Platform.Source"= @{ VDIState="Unchanged"; URL="https://learn.microsoft.com/en-us/windows/package-manager/winget/"; Description="Winget source" } - "Microsoft.Xbox.TCUI" = @{ VDIState="Unchanged"; URL="https://docs.microsoft.com/en-us/gaming/xbox-live/features/general/tcui/live-tcui-overview"; Description="Xbox TCUI" } - "Microsoft.XboxIdentityProvider" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/xbox-identity-provider/9wzdncrd1hkw"; Description="Xbox Identity Provider" } - "Microsoft.XboxSpeechToTextOverlay" = @{ VDIState="Unchanged"; URL="https://support.xbox.com/help/account-profile/accessibility/use-game-chat-transcription"; Description="Xbox chat transcription" } - "Microsoft.YourPhone" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/Your-phone/9nmpj99vjbwv"; Description="Phone Link" } - "Microsoft.ZuneMusic" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/groove-music/9wzdncrfj3pt"; Description="Groove Music" } - "Microsoft.ZuneVideo" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/movies-tv/9wzdncrfj3p2"; Description="Movies & TV" } - "MicrosoftCorporationII.QuickAssist" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/9P7BP5VNWKX5?hl=en-us&gl=US"; Description="Quick Assist" } - "MicrosoftWindows.Client.WebExperience" = @{ VDIState="Unchanged"; URL=""; Description="Windows 11 Web Experience" } - "Microsoft.XboxApp" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/store/apps/9wzdncrfjbd8"; Description="Xbox Console Companion" } - "Microsoft.MixedReality.Portal" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/mixed-reality-portal/9ng1h8b3zc7m"; Description="Mixed Reality Portal" } - "Microsoft.Microsoft3DViewer" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/p/3d-viewer/9nblggh42ths"; Description="3D Viewer" } - "MicrosoftTeams" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/xp8bt8dw290mpq"; Description="Microsoft Teams" } - "MSTeams" = @{ VDIState="Unchanged"; URL="https://apps.microsoft.com/detail/xp8bt8dw290mpq"; Description="Microsoft Teams (alt id)" } - "Microsoft.OneDriveSync" = @{ VDIState="Unchanged"; URL="https://docs.microsoft.com/en-us/onedrive/one-drive-sync"; Description="OneDrive sync app" } - "Microsoft.Wallet" = @{ VDIState="Unchanged"; URL="https://www.microsoft.com/en-us/payments"; Description="Microsoft Pay" } - } - - foreach ($Key in $apps.Keys) { - try { - Write-Log -message ("uninstall_appx_packages :: removing AppX match: {0}" -f $Key) -severity 'DEBUG' - - # Run each key's removal in a job with a timeout so we never hang forever. - $ok = Invoke-WithTimeout -TimeoutSeconds 180 -ScriptBlock ([scriptblock]::Create(@" -`$ErrorActionPreference = 'Continue' -`$Key = '$($Key.Replace("'","''"))' - -# Provisioned packages (image-level) -try { - Get-AppxProvisionedPackage -Online -ErrorAction Stop | - Where-Object { `$_.PackageName -like ("*{0}*" -f `$Key) } | - ForEach-Object { - `$pkgName = `$_.PackageName - try { Remove-AppxProvisionedPackage -Online -PackageName `$pkgName -ErrorAction Stop | Out-Null } catch { } - } -} catch { } - -# Installed packages (all users) -try { - Get-AppxPackage -AllUsers -Name ("*{0}*" -f `$Key) -ErrorAction SilentlyContinue | - ForEach-Object { - `$full = `$_.PackageFullName - try { Remove-AppxPackage -AllUsers -Package `$full -ErrorAction Stop | Out-Null } catch { } - } -} catch { } - -# Installed packages (current user) -try { - Get-AppxPackage -Name ("*{0}*" -f `$Key) -ErrorAction SilentlyContinue | - ForEach-Object { - `$full = `$_.PackageFullName - try { Remove-AppxPackage -Package `$full -ErrorAction Stop | Out-Null } catch { } - } -} catch { } -"@)) - - if (-not $ok) { - Write-Log -message ("uninstall_appx_packages :: timeout while removing key: {0}" -f $Key) -severity 'WARN' - } - } catch { - Write-Log -message ("Remove-PreinstalledAppxPackages unexpected failure for key {0}: {1}" -f $Key, $_.Exception.ToString()) -severity 'WARN' - continue - } - } -} - -function Disable-AppXSvcCore { - [CmdletBinding()] - param() - - $svc = Get-Service -Name $svcName -ErrorAction SilentlyContinue - if ($null -ne $svc) { - if ($svc.Status -ne 'Stopped') { - Stop-Service -Name $svcName -Force -ErrorAction SilentlyContinue - } - Set-Service -Name $svcName -StartupType Disabled -ErrorAction SilentlyContinue - } - - # Extra-hard disable (best-effort): do NOT allow sc.exe exit code to poison overall script exit code - try { & sc.exe config $svcName start= disabled | Out-Null } catch { } finally { $global:LASTEXITCODE = 0 } - - # Registry is the source of truth for disabled start - if (Test-Path $svcKeyPath) { - New-ItemProperty -Path $svcKeyPath -Name Start -Value 4 -PropertyType DWord -Force | Out-Null - } -} - -function Ensure-AppXSvcHardeningTask { - [CmdletBinding()] - param() - - $hardeningDir = 'C:\ProgramData\AppXLock' - $hardeningFile = Join-Path $hardeningDir 'Disable-AppXSvc.ps1' - - if (-not (Test-Path $hardeningDir)) { - New-Item -ItemType Directory -Path $hardeningDir -Force | Out-Null - } - - $hardeningScript = @' -param() - -$ErrorActionPreference = "SilentlyContinue" - -$svcName = "AppXSvc" -$svcKeyPath = "HKLM:\SYSTEM\CurrentControlSet\Services\AppXSvc" - -try { - $svc = Get-Service -Name $svcName -ErrorAction SilentlyContinue - if ($null -ne $svc) { - if ($svc.Status -ne "Stopped") { Stop-Service -Name $svcName -Force -ErrorAction SilentlyContinue } - Set-Service -Name $svcName -StartupType Disabled -ErrorAction SilentlyContinue - } - - try { & sc.exe config $svcName start= disabled | Out-Null } catch { } finally { $global:LASTEXITCODE = 0 } - - if (Test-Path $svcKeyPath) { - New-ItemProperty -Path $svcKeyPath -Name Start -Value 4 -PropertyType DWord -Force | Out-Null - } -} catch { - # best-effort only -} -'@ - - Set-Content -Path $hardeningFile -Value $hardeningScript -Encoding UTF8 -Force - - $action = New-ScheduledTaskAction -Execute 'powershell.exe' ` - -Argument "-NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$hardeningFile`"" - $trigger = New-ScheduledTaskTrigger -AtStartup - - $taskName = 'Hard-Disable-AppXSvc' - $taskPath = '\Hardening\' - - # Ensure Task Scheduler service is running (best-effort) - try { Start-Service -Name Schedule -ErrorAction SilentlyContinue } catch { } - - # Register task with retries (Task Scheduler can be flaky) - $max = 5 - for ($i=1; $i -le $max; $i++) { - try { - Unregister-ScheduledTask -TaskName $taskName -TaskPath $taskPath -Confirm:$false -ErrorAction SilentlyContinue - Register-ScheduledTask -TaskName $taskName -TaskPath $taskPath -Action $action -Trigger $trigger -RunLevel Highest -User 'SYSTEM' -Force | Out-Null - return - } catch { - Write-Log -message ("Ensure-AppXSvcHardeningTask :: Register-ScheduledTask failed ({0}/{1}): {2}" -f $i,$max,$_.Exception.Message) -severity 'WARN' - Start-Sleep -Seconds 3 - if ($i -eq $max) { throw } - } - } -} - -function Test-AppXSvcDisabled { - [CmdletBinding()] - param() - - $svc = Get-Service -Name $svcName -ErrorAction SilentlyContinue - if ($null -eq $svc) { return $true } - - $regStart = $null - try { $regStart = (Get-ItemProperty -Path $svcKeyPath -Name Start -ErrorAction SilentlyContinue).Start } catch { } - $regDisabled = ($regStart -eq 4) - - $cimDisabled = $false - try { - $svcCim = Get-CimInstance Win32_Service -Filter "Name='$svcName'" -ErrorAction SilentlyContinue - if ($svcCim) { $cimDisabled = ($svcCim.StartMode -eq 'Disabled') } - } catch { } - - if ($svc.Status -eq 'Stopped' -and ($regDisabled -or $cimDisabled)) { return $true } - return $false -} -# --------------------------------------------------------------------------- -# Skip AppX uninstall for ref pools -# --------------------------------------------------------------------------- -try { - $rpKey = 'HKLM:\SOFTWARE\Mozilla\ronin_puppet' - $wpId = (Get-ItemProperty -Path $rpKey -Name 'worker_pool_id' -ErrorAction Stop).worker_pool_id - - $skipNeedles = @( - 'win11-64-24h2-hw-ref-alpha', - 'win11-64-24h2-hw-ref' - ) - - foreach ($needle in $skipNeedles) { - if ($wpId -like "*$needle*") { - Write-Log -message "uninstall_appx_packages :: SKIP: worker_pool_id='$wpId' matched '$needle' (ref pool). Exiting 0." -severity 'INFO' - Stop-TranscriptSafe - exit 0 - } - } - - Write-Log -message "uninstall_appx_packages :: worker_pool_id='$wpId' did not match ref pools; continuing." -severity 'DEBUG' -} -catch { - # If you *never* want this to block the run, log and continue. - Write-Log -message "uninstall_appx_packages :: WARN: could not read worker_pool_id from registry ($($_.Exception.Message)); continuing." -severity 'WARN' -} -# --------------------------------------------------------------------------- -# Main -# --------------------------------------------------------------------------- -try { - Write-Log -message 'uninstall_appx_packages :: begin' -severity 'DEBUG' - - Write-Log -message 'uninstall_appx_packages :: Wait-AppxIdle' -severity 'DEBUG' - Wait-AppxIdle -TimeoutSeconds 600 -SleepSeconds 15 | Out-Null - - Write-Log -message 'uninstall_appx_packages :: Remove-PreinstalledAppxPackages' -severity 'DEBUG' - Remove-PreinstalledAppxPackages - - Write-Log -message 'uninstall_appx_packages :: Disable-AppXSvcCore' -severity 'DEBUG' - Disable-AppXSvcCore - - Write-Log -message 'uninstall_appx_packages :: Ensure-AppXSvcHardeningTask' -severity 'DEBUG' - Ensure-AppXSvcHardeningTask - - # Re-apply after task registration (SCM can flip it back briefly) - Write-Log -message 'uninstall_appx_packages :: Disable-AppXSvcCore (post-task)' -severity 'DEBUG' - Disable-AppXSvcCore - - # Verify with retries - $max = 10 - for ($i = 1; $i -le $max; $i++) { - if (Test-AppXSvcDisabled) { break } - Write-Log -message ("uninstall_appx_packages :: waiting for AppXSvc to disable ({0}/{1})" -f $i, $max) -severity 'DEBUG' - Start-Sleep -Seconds 2 - Disable-AppXSvcCore - } - - if (-not (Test-AppXSvcDisabled)) { - $svc = Get-Service -Name $svcName -ErrorAction SilentlyContinue - $status = if ($svc) { $svc.Status } else { 'Missing' } - - $regStart = $null - try { $regStart = (Get-ItemProperty -Path $svcKeyPath -Name Start -ErrorAction SilentlyContinue).Start } catch { } - $regStartStr = if ($null -ne $regStart) { $regStart } else { 'Missing' } - - $cimStartMode = 'Unknown' - try { - $svcCim = Get-CimInstance Win32_Service -Filter "Name='$svcName'" -ErrorAction SilentlyContinue - if ($svcCim) { $cimStartMode = $svcCim.StartMode } - } catch { } - - Write-Log -message ("uninstall_appx_packages :: AppXSvc is NOT disabled. Status: {0}, RegStart: {1}, CimStartMode: {2}" -f $status, $regStartStr, $cimStartMode) -severity 'ERROR' - Stop-TranscriptSafe - exit 2 - } - - Write-Log -message 'uninstall_appx_packages :: complete (AppXSvc disabled)' -severity 'DEBUG' - Stop-TranscriptSafe - exit 0 -} -catch { - $msg = "uninstall_appx_packages :: FATAL: $($_.Exception.ToString())" - try { Write-Output $msg } catch { } - Write-Log -message $msg -severity 'ERROR' - Stop-TranscriptSafe - exit 1 -}