Files
winutil/functions/private/Invoke-WinUtilTweaks.ps1
T
Omar 07ccd8e2e7 fix(tweaks): skip missing services instead of aborting the run (#5140)
Invoke-WinUtilTweaks caught a missing service with [System.ServiceProcess.ServiceNotFoundException], a type that does not exist in .NET. PowerShell could not resolve the catch type, so the missing-service case aborted the whole tweaks job rather than warning.

Catch on the error ID the way Set-WinUtilService already does: an absent service warns and logs, and any unrelated lookup failure is rethrown. The Tweaks guide documents the skip.
2026-10-07 09:43:22 -05:00

101 lines
3.8 KiB
PowerShell

function Invoke-WinUtilTweaks {
<#
.SYNOPSIS
Invokes the function associated with each provided checkbox
.PARAMETER CheckBox
The checkbox to invoke
.PARAMETER undo
Indicates whether to undo the operation contained in the checkbox
.PARAMETER KeepServiceStartup
Indicates whether to override the startup of a service with the one given from WinUtil,
or to keep the startup of said service, if it was changed by the user, or another program, from its default value.
#>
param(
$CheckBox,
$undo = $false,
$KeepServiceStartup = $true
)
$action = if ($undo) { "Undo" } else { "Apply" }
Write-WinUtilLog -Component "Tweaks" -Message "$action tweak: $CheckBox"
# The counter lives in this runspace, so an error a concurrent job logs from its own
# runspace cannot be charged to a toggle flipped on the UI thread
$errorsBefore = [int]$global:WinUtilJobErrorCount
if ($undo) {
$Values = @{
Registry = "OriginalValue"
Service = "OriginalType"
ScriptType = "UndoScript"
}
} else {
$Values = @{
Registry = "Value"
Service = "StartupType"
OriginalService = "OriginalType"
ScriptType = "InvokeScript"
}
}
if ($sync.configs.tweaks.$CheckBox.service) {
$sync.configs.tweaks.$CheckBox.service | ForEach-Object {
$changeservice = $true
# The check for !($undo) is required, without it the script will throw an error for accessing unavailable member, which's the 'OriginalService' Property
if ($KeepServiceStartup -AND !($undo)) {
$serviceName = $psitem.Name
try {
# Check if the service exists
$service = Get-Service -Name $serviceName -ErrorAction Stop
if(!($service.StartType.ToString() -eq $psitem.$($values.OriginalService))) {
$changeservice = $false
}
} catch {
if ($_.FullyQualifiedErrorId -like "NoServiceFoundForGivenName,*") {
$changeservice = $false
Write-Warning "Service $serviceName was not found."
Write-WinUtilLog -Level "WARN" -Component "Service" -Message "Service $serviceName was not found."
} else {
throw
}
}
}
if ($changeservice) {
Set-WinUtilService -Name $psitem.Name -StartupType $psitem.$($values.Service)
}
}
}
if ($sync.configs.tweaks.$CheckBox.registry) {
$sync.configs.tweaks.$CheckBox.registry | Where-Object { -not $psitem.Values } | ForEach-Object {
Set-WinUtilRegistry -Name $psitem.Name -Path $psitem.Path -Type $psitem.Type -Value $psitem.$($values.registry)
}
}
if ($sync.configs.tweaks.$CheckBox.$($values.ScriptType)) {
$sync.configs.tweaks.$CheckBox.$($values.ScriptType) | ForEach-Object {
$Scriptblock = [scriptblock]::Create($psitem)
Invoke-WinUtilScript -ScriptBlock $scriptblock -Name $CheckBox
}
}
if (!$undo) {
if($sync.configs.tweaks.$CheckBox.appx) {
$sync.configs.tweaks.$CheckBox.appx | ForEach-Object {
Remove-WinUtilAPPX -Name $psitem
}
Remove-WinUtilProvisionedAPPX -PackageList $sync.configs.tweaks.$CheckBox.appx
}
}
$errorCount = [int]$global:WinUtilJobErrorCount - $errorsBefore
if ($errorCount -gt 0) {
Write-WinUtilLog -Level "WARN" -Component "Tweaks" -Message "$action tweak finished with $errorCount error(s): $CheckBox"
} else {
Write-WinUtilLog -Component "Tweaks" -Message "$action tweak completed: $CheckBox"
}
}