Files
winutil/functions/private/Set-WinUtilRegistry.ps1
T
Phuc ToandGitHub 6de45a38b9 Fix UI helper errors during headless -Preset and -Config runs (#4941)
* Make UI helpers no-op when no window exists

The -Preset and -Config paths run Invoke-WinUtilAutoRun before the XAML
form is created and before PresentationCore is loaded, so every call into
Invoke-WPFUIThread failed with InvokeMethodOnNull and every call into
Set-WinUtilTweaksProgressIndicator failed to resolve [Windows.Visibility].
The errors were non-terminating, so tweaks still applied, but each run
filled the log with noise.

Loading presentationframework earlier does not help: Visibility lives in
PresentationCore, which only loads once a WPF object is instantiated, and
the XAML-named progress controls do not exist in these paths either.
Guarding the two helpers covers Invoke-WPFtweaksbutton, Invoke-WPFundoall
and Invoke-WPFFeatureInstall, which the existing per-call-site $hasUI
convention never reached.

* Suppress stray console output from automation runs

Invoke-WPFRunspace returns an IAsyncResult that no caller uses, and
Set-WinUtilRegistry was the only New-PSDrive call site that did not
suppress its output. A GUI click handler discards both, but the -Preset
and -Config paths call the workflows directly, so an async handle dump
and a PSDrive table landed in the user's log.

The handle itself is kept because pester/runspace.Tests.ps1 asserts that
Invoke-WPFRunspace returns a single IAsyncResult, so the suppression goes
at the four call sites reachable from Invoke-WinUtilAutoRun.

* Add project learning for window-free UI helpers
2026-08-09 13:06:17 -05:00

64 lines
2.6 KiB
PowerShell

function Set-WinUtilRegistry {
<#
.SYNOPSIS
Modifies the registry based on the given inputs
.PARAMETER Name
The name of the key to modify
.PARAMETER Path
The path to the key
.PARAMETER Type
The type of value to set the key to
.PARAMETER Value
The value to set the key to
.EXAMPLE
Set-WinUtilRegistry -Name "PublishUserActivities" -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Type "DWord" -Value "0"
#>
param (
$Name,
$Path,
$Type,
$Value
)
try {
if(!(Test-Path 'HKU:\')) {New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS | Out-Null}
If (!(Test-Path $Path)) {
Write-Host "$Path was not found. Creating..."
Write-WinUtilLog -Component "Registry" -Message "Creating registry path: $Path"
New-Item -Path $Path -Force -ErrorAction Stop | Out-Null
}
if ($Value -ne "<RemoveEntry>") {
Write-Host "Set $Path\$Name to $Value"
Write-WinUtilLog -Component "Registry" -Message "Setting $Path\$Name ($Type) to $Value"
Set-ItemProperty -Path $Path -Name $Name -Type $Type -Value $Value -Force -ErrorAction Stop | Out-Null
}
else{
Write-Host "Remove $Path\$Name"
Write-WinUtilLog -Component "Registry" -Message "Removing $Path\$Name"
Remove-ItemProperty -Path $Path -Name $Name -Force -ErrorAction Stop | Out-Null
}
} catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception."
Write-WinUtilLog -Level "ERROR" -Component "Registry" -Message "Security exception while changing $Path\$Name to $Value`: $($psitem.Exception.Message)"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
Write-WinUtilLog -Level "ERROR" -Component "Registry" -Message "Registry item not found while changing $Path\$Name`: $($psitem.Exception.Message)"
} catch [System.UnauthorizedAccessException] {
Write-Warning $psitem.Exception.Message
Write-WinUtilLog -Level "ERROR" -Component "Registry" -Message "Unauthorized while changing $Path\$Name`: $($psitem.Exception.Message)"
} catch {
Write-Warning "Unable to set $Name due to unhandled exception."
Write-Warning $psitem.Exception.StackTrace
Write-WinUtilLog -Level "ERROR" -Component "Registry" -Message "Unhandled exception while changing $Path\$Name`: $($psitem.Exception.Message)"
}
}