Files
winutil/functions/private/Set-WinUtilRegistryComboState.ps1
T
OmarandGitHub bc607b6c91 Make MPO tweak a three-state control (#4897)
* refactor: make MPO tweak a three-state control

* docs: explain MPO tweak states

* docs: address code review comments

* refactor: make Multiplane Overlay config-driven
2026-08-09 14:02:42 -05:00

79 lines
3.4 KiB
PowerShell

function Set-WinUtilRegistryComboState {
<#
.SYNOPSIS
Applies and verifies a config-defined registry combo-box state.
.PARAMETER Registry
Registry settings containing a value mapping for each supported state.
.PARAMETER State
The state name to apply.
#>
param(
[Parameter(Mandatory)]
$Registry,
[Parameter(Mandatory)]
[string]$State
)
if ($Registry[0].Values.PSObject.Properties.Name -notcontains $State) {
throw "Unknown registry state '$State'."
}
# Preserve exact prior values so a partial update can be rolled back.
$previousValues = foreach ($setting in @($Registry)) {
$currentValue = Get-WinUtilRegistryComboValue -Setting $setting
[pscustomobject]@{ Setting = $setting; Exists = $currentValue.Exists; Value = $currentValue.Value }
}
try {
foreach ($setting in @($Registry)) {
$configuredValue = $setting.Values.PSObject.Properties[$State].Value
$previousValue = $previousValues | Where-Object Setting -EQ $setting
if ($configuredValue -ne "<RemoveEntry>" -or $previousValue.Exists) {
Set-WinUtilRegistry -Name $setting.Name -Path $setting.Path -Type $setting.Type -Value $configuredValue
}
}
# Set-WinUtilRegistry reports write errors without throwing, so verify each result explicitly.
foreach ($setting in @($Registry)) {
$configuredValue = $setting.Values.PSObject.Properties[$State].Value
$currentValue = Get-WinUtilRegistryComboValue -Setting $setting
$writeMatches = if ($configuredValue -eq "<RemoveEntry>") {
-not $currentValue.Exists
} else {
$currentValue.Exists -and [string]$currentValue.Value -eq [string]$configuredValue
}
if (-not $writeMatches) {
throw "The registry values did not match the requested state."
}
}
} catch {
$applyError = $_.Exception.Message
if ([string]::IsNullOrWhiteSpace($applyError)) {
$applyError = "The registry values did not match the requested state."
}
$rollbackFailed = $false
foreach ($previousValue in $previousValues) {
try {
$currentValue = Get-WinUtilRegistryComboValue -Setting $previousValue.Setting
if ($previousValue.Exists -or $currentValue.Exists) {
$rollbackValue = if ($previousValue.Exists) { $previousValue.Value } else { "<RemoveEntry>" }
Set-WinUtilRegistry -Name $previousValue.Setting.Name -Path $previousValue.Setting.Path -Type $previousValue.Setting.Type -Value $rollbackValue
}
$restoredValue = Get-WinUtilRegistryComboValue -Setting $previousValue.Setting
if ($restoredValue.Exists -ne $previousValue.Exists -or ($restoredValue.Exists -and [string]$restoredValue.Value -ne [string]$previousValue.Value)) {
$rollbackFailed = $true
}
} catch {
$rollbackFailed = $true
}
}
if ($rollbackFailed) {
throw "Unable to apply registry state '$State': $applyError. The previous registry state could not be restored."
}
throw "Unable to apply registry state '$State': $applyError"
}
}