diff --git a/test.ps1 b/test.ps1 index 51c6ba5..d948ea8 100644 --- a/test.ps1 +++ b/test.ps1 @@ -235,16 +235,12 @@ function Invoke-ServiceImagePathAudit { return $outObj } - # Normalize root names so reg.exe remote paths are valid - $regKey = [string]$outObj.Key - $regKey = $regKey -replace '^HKEY_LOCAL_MACHINE', 'HKLM' - $regKey = $regKey -replace '^HKEY_USERS', 'HKU' - - $target = "\\$($outObj.ComputerName)\$regKey" - $data = [string]$outObj.FixedKey + $computer = [string]$outObj.ComputerName + $fullKey = [string]$outObj.Key + $data = [string]$outObj.FixedKey if ($ShowProgress) { - Write-Progress -Activity "Repairing ImagePath" -Status "Fixing $($outObj.ComputerName)\$regKey" + Write-Progress -Activity "Repairing ImagePath" -Status "Fixing $computer" } if ([string]::IsNullOrWhiteSpace($data) -or $data -eq 'N/A' -or $data -eq "Can't Fix") { @@ -252,34 +248,50 @@ function Invoke-ServiceImagePathAudit { return $outObj } - # reg.exe needs embedded quotes escaped, and the whole /d value wrapped in quotes - # Example: "C:\Program Files\App\app.exe" /arg - # becomes: "\"C:\Program Files\App\app.exe\" /arg" - $dataEscaped = $data -replace '"', '\"' - $dataForReg = '"' + $dataEscaped + '"' + # Determine hive + subkey from the Key string we scanned + $hive = $null + $subKeyPath = $null - if ($PSCmdlet.ShouldProcess($target, "Set ImagePath to: $data")) { + if ($fullKey -match '^(HKEY_LOCAL_MACHINE|HKLM)\\(?.+)$') { + $hive = [Microsoft.Win32.RegistryHive]::LocalMachine + $subKeyPath = $Matches['sub'] + } + elseif ($fullKey -match '^(HKEY_USERS|HKU)\\(?.+)$') { + $hive = [Microsoft.Win32.RegistryHive]::Users + $subKeyPath = $Matches['sub'] + } + else { + $outObj.Status = "Failed: Unsupported registry root in Key: $fullKey" + return $outObj + } + + if ($PSCmdlet.ShouldProcess("$computer\$fullKey", "Set ImagePath to: $data")) { try { - $args = @( - 'ADD', $target, - '/v', 'ImagePath', - '/t', 'REG_EXPAND_SZ', - '/d', $dataForReg, - '/f' - ) + # Open remote HKLM/HKU + $base = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hive, $computer) - $output = & reg.exe @args 2>&1 - - if ($LASTEXITCODE -eq 0) { - $outObj.Status = "Fixed" - } else { - $msg = ($output | Out-String).Trim() - if ([string]::IsNullOrWhiteSpace($msg)) { $msg = "reg.exe exit code $LASTEXITCODE" } - $outObj.Status = "Failed: $msg" + # Open the service key writable + $svcKey = $base.OpenSubKey($subKeyPath, $true) + if ($null -eq $svcKey) { + $outObj.Status = "Failed: Registry key not found: $fullKey" + return $outObj } + + try { + # Write as REG_EXPAND_SZ (ExpandString) + $svcKey.SetValue('ImagePath', $data, [Microsoft.Win32.RegistryValueKind]::ExpandString) + } + finally { + $svcKey.Close() + $base.Close() + } + + $outObj.Status = "Fixed" } catch { - $outObj.Status = "Failed: $($_.Exception.Message)" + $msg = $_.Exception.Message + if ([string]::IsNullOrWhiteSpace($msg)) { $msg = "$_" } + $outObj.Status = "Failed: $msg" } } else { @@ -289,6 +301,7 @@ function Invoke-ServiceImagePathAudit { return $outObj } + } process {