From 31646112bf3793b8a08862bcbcca927ffa0c037d Mon Sep 17 00:00:00 2001 From: X9 Date: Sat, 14 Mar 2026 19:37:47 +0100 Subject: [PATCH] Fix registry ACL errors in steps 3 and 4 - 03-system-registry.ps1: add Grant-RegWriteAccess helper; Set-Reg now retries with ACL fix when Set-ItemProperty throws SecurityException (e.g. HKLM\...\Communications owned by TrustedInstaller) - 04-default-profile.ps1: add Grant-HiveWriteAccess helper; Set-ProfileReg retries with ACL fix on Default hive keys with restricted permissions - Both scripts: add -ErrorAction Stop to Set-ItemProperty so errors are properly caught by try/catch instead of bypassing it Co-Authored-By: Claude Sonnet 4.6 --- scripts/03-system-registry.ps1 | 59 ++++++++++++++++++++++++++++++++-- scripts/04-default-profile.ps1 | 41 ++++++++++++++++++++--- 2 files changed, 92 insertions(+), 8 deletions(-) diff --git a/scripts/03-system-registry.ps1 b/scripts/03-system-registry.ps1 index d4a759d..a3e4f2a 100644 --- a/scripts/03-system-registry.ps1 +++ b/scripts/03-system-registry.ps1 @@ -11,6 +11,48 @@ function Write-Log { Add-Content -Path $LogFile -Value $line -Encoding UTF8 } +function Grant-RegWriteAccess { + param([string]$Path) + # Grants Administrators FullControl on a registry key that has restricted ACL. + # Required for keys owned by TrustedInstaller or with locked-down ACL. + try { + $hive = $Path -replace '^(HKLM|HKCU|HKU|HKCR|HKCC):\\.*', '$1' + $subkey = $Path -replace '^(HKLM|HKCU|HKU|HKCR|HKCC):\\', '' + $rootKey = switch ($hive) { + "HKLM" { [Microsoft.Win32.Registry]::LocalMachine } + "HKCU" { [Microsoft.Win32.Registry]::CurrentUser } + "HKCR" { [Microsoft.Win32.Registry]::ClassesRoot } + } + $rights = [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree + $regRights = [System.Security.AccessControl.RegistryRights]::TakeOwnership + $key = $rootKey.OpenSubKey($subkey, $rights, $regRights) + if ($key) { + $acl = $key.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None) + $acl.SetOwner([System.Security.Principal.NTAccount]"BUILTIN\Administrators") + $key.SetAccessControl($acl) + $key.Close() + } + # Re-open with ChangePermissions to grant full control + $key = $rootKey.OpenSubKey($subkey, $rights, [System.Security.AccessControl.RegistryRights]::ChangePermissions) + if ($key) { + $acl = $key.GetAccessControl() + $rule = New-Object System.Security.AccessControl.RegistryAccessRule( + "BUILTIN\Administrators", + [System.Security.AccessControl.RegistryRights]::FullControl, + [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit", + [System.Security.AccessControl.PropagationFlags]::None, + [System.Security.AccessControl.AccessControlType]::Allow + ) + $acl.SetAccessRule($rule) + $key.SetAccessControl($acl) + $key.Close() + } + } + catch { + Write-Log " Grant-RegWriteAccess failed for $Path - $_" -Level WARN + } +} + function Set-Reg { param( [string]$Path, @@ -20,13 +62,24 @@ function Set-Reg { ) try { if (-not (Test-Path $Path)) { - New-Item -Path $Path -Force | Out-Null + New-Item -Path $Path -Force -ErrorAction Stop | Out-Null } - Set-ItemProperty -Path $Path -Name $Name -Value $Value -Type $Type -Force + Set-ItemProperty -Path $Path -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop Write-Log " SET $Path\$Name = $Value" -Level OK } catch { - Write-Log " FAILED $Path\$Name - $_" -Level ERROR + # Retry after granting write access + try { + Grant-RegWriteAccess -Path $Path + if (-not (Test-Path $Path)) { + New-Item -Path $Path -Force -ErrorAction Stop | Out-Null + } + Set-ItemProperty -Path $Path -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop + Write-Log " SET $Path\$Name = $Value (after ACL fix)" -Level OK + } + catch { + Write-Log " FAILED $Path\$Name - $_" -Level ERROR + } } } diff --git a/scripts/04-default-profile.ps1 b/scripts/04-default-profile.ps1 index 225d22b..60acfa3 100644 --- a/scripts/04-default-profile.ps1 +++ b/scripts/04-default-profile.ps1 @@ -14,6 +14,26 @@ function Write-Log { # ----------------------------------------------------------------------- # Helper - apply a registry setting to both Default hive and current HKCU # ----------------------------------------------------------------------- +function Grant-HiveWriteAccess { + param([string]$HivePath) # full path e.g. "Registry::HKU\DefaultProfile\Software\..." + # Grants Administrators FullControl on a loaded hive key with restricted ACL. + try { + $acl = Get-Acl -Path $HivePath -ErrorAction Stop + $rule = New-Object System.Security.AccessControl.RegistryAccessRule( + "BUILTIN\Administrators", + [System.Security.AccessControl.RegistryRights]::FullControl, + [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit", + [System.Security.AccessControl.PropagationFlags]::None, + [System.Security.AccessControl.AccessControlType]::Allow + ) + $acl.SetAccessRule($rule) + Set-Acl -Path $HivePath -AclObject $acl -ErrorAction Stop + } + catch { + Write-Log " Grant-HiveWriteAccess failed for $HivePath - $_" -Level WARN + } +} + function Set-ProfileReg { param( [string]$SubKey, # relative to HKCU (e.g. "Software\Microsoft\...") @@ -26,21 +46,32 @@ function Set-ProfileReg { $defPath = "Registry::HKU\DefaultProfile\$SubKey" try { if (-not (Test-Path $defPath)) { - New-Item -Path $defPath -Force | Out-Null + New-Item -Path $defPath -Force -ErrorAction Stop | Out-Null } - Set-ItemProperty -Path $defPath -Name $Name -Value $Value -Type $Type -Force + Set-ItemProperty -Path $defPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop } catch { - Write-Log " DEFAULT HIVE failed $SubKey\$Name - $_" -Level ERROR + # Retry after granting write access to parent key + try { + $parentPath = $defPath -replace '\\[^\\]+$', '' + if (Test-Path $parentPath) { Grant-HiveWriteAccess -HivePath $parentPath } + if (-not (Test-Path $defPath)) { + New-Item -Path $defPath -Force -ErrorAction Stop | Out-Null + } + Set-ItemProperty -Path $defPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop + } + catch { + Write-Log " DEFAULT HIVE failed $SubKey\$Name - $_" -Level ERROR + } } # Apply to current user as well $hkcuPath = "HKCU:\$SubKey" try { if (-not (Test-Path $hkcuPath)) { - New-Item -Path $hkcuPath -Force | Out-Null + New-Item -Path $hkcuPath -Force -ErrorAction Stop | Out-Null } - Set-ItemProperty -Path $hkcuPath -Name $Name -Value $Value -Type $Type -Force + Set-ItemProperty -Path $hkcuPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop Write-Log " SET $SubKey\$Name = $Value" -Level OK } catch {