From b041d2de03f1c893e0ace40dbf03dc3c65c6f416 Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Wed, 3 Aug 2016 01:03:23 -0500 Subject: [PATCH] (GH-375) HKCU may not have Environment When attempting to expand or work with `HKCU:\Environment`, that can error due to not having an existing `Environment` key in HKCU. This can occur in certain Windows Server versions, such as Server Core which doesn't have the key. This can also happen in other situations as well. - In `Get-EnvironmentVariableNames`, when expanding from `HKCU:\Environment` and it fails, silently continue. - When attempting to remove variables at User scope for Get-ToolsLocation, fail those silently. - If you can't set the Get-ToolsLocation value for User scope, attempt Machine scope instead. - With `Install-ChocolateyEnvironmentVariable`, if the attempt to set to User scope fails and the user is an administrator, attempt to set it with Machine scope. Otherwise fail. - In `Get-EnvironmentVariable`, if the registry key is null, do not attempt to grab a value or close it. --- .../functions/Get-EnvironmentVariable.ps1 | 9 +++++++-- .../functions/Get-EnvironmentVariableNames.ps1 | 3 ++- .../helpers/functions/Get-ToolsLocation.ps1 | 17 +++++++++++++---- .../Install-ChocolateyEnvironmentVariable.ps1 | 11 ++++++++++- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/chocolatey.resources/helpers/functions/Get-EnvironmentVariable.ps1 b/src/chocolatey.resources/helpers/functions/Get-EnvironmentVariable.ps1 index c3b99b3b7f..de6d75343c 100644 --- a/src/chocolatey.resources/helpers/functions/Get-EnvironmentVariable.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-EnvironmentVariable.ps1 @@ -81,11 +81,16 @@ param( try { #Write-Verbose "Getting environment variable $Name" - $environmentVariableValue = $win32RegistryKey.GetValue($Name, [string]::Empty, $registryValueOptions) + if ($win32RegistryKey -ne $null) { + # Some versions of Windows do not have HKCU:\Environment + $environmentVariableValue = $win32RegistryKey.GetValue($Name, [string]::Empty, $registryValueOptions) + } } catch { Write-Debug "Unable to retrieve the $Name environment variable. Details: $_" } finally { - $win32RegistryKey.Close() + if ($win32RegistryKey -ne $null) { + $win32RegistryKey.Close() + } } if ($environmentVariableValue -eq $null -or $environmentVariableValue -eq '') { diff --git a/src/chocolatey.resources/helpers/functions/Get-EnvironmentVariableNames.ps1 b/src/chocolatey.resources/helpers/functions/Get-EnvironmentVariableNames.ps1 index 74c54f08ba..fc91d55d72 100644 --- a/src/chocolatey.resources/helpers/functions/Get-EnvironmentVariableNames.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-EnvironmentVariableNames.ps1 @@ -45,8 +45,9 @@ Get-EnvironmentVariable Set-EnvironmentVariable #> + # HKCU:\Environment may not exist in all Windows OSes (such as Server Core). switch ($Scope) { - 'User' { Get-Item 'HKCU:\Environment' | Select-Object -ExpandProperty Property } + 'User' { Get-Item 'HKCU:\Environment' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Property } 'Machine' { Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' | Select-Object -ExpandProperty Property } 'Process' { Get-ChildItem Env:\ | Select-Object -ExpandProperty Key } default { throw "Unsupported environment scope: $Scope" } diff --git a/src/chocolatey.resources/helpers/functions/Get-ToolsLocation.ps1 b/src/chocolatey.resources/helpers/functions/Get-ToolsLocation.ps1 index 4055078ab7..1f9c9c2df0 100644 --- a/src/chocolatey.resources/helpers/functions/Get-ToolsLocation.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-ToolsLocation.ps1 @@ -62,21 +62,30 @@ None if ($binRoot -eq $null) { $binRoot = $olderRoot } - Set-EnvironmentVariable -Name "chocolatey_bin_root" -Value '' -Scope User + Set-EnvironmentVariable -Name "chocolatey_bin_root" -Value '' -Scope User -ErrorAction SilentlyContinue } $toolsLocation = $binRoot - Set-EnvironmentVariable -Name "ChocolateyBinRoot" -Value '' -Scope User + Set-EnvironmentVariable -Name "ChocolateyBinRoot" -Value '' -Scope User -ErrorAction SilentlyContinue } } # Add a drive letter if one doesn't exist if (-not($toolsLocation -imatch "^\w:")) { - $toolsLocation = join-path $env:systemdrive $toolsLocation + $toolsLocation = Join-Path $env:systemdrive $toolsLocation } if (-not($env:ChocolateyToolsLocation -eq $toolsLocation)) { - Set-EnvironmentVariable -Name "ChocolateyToolsLocation" -Value $toolsLocation -Scope User + try { + Set-EnvironmentVariable -Name "ChocolateyToolsLocation" -Value $toolsLocation -Scope User + } catch { + if (Test-ProcessAdminRights) { + # sometimes User scope may not exist (such as with core) + Set-EnvironmentVariable -Name "ChocolateyToolsLocation" -Value $toolsLocation -Scope Machine + } else { + throw $_.Exception + } + } } return $toolsLocation diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyEnvironmentVariable.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyEnvironmentVariable.ps1 index 628168dc2a..09ba1635d2 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyEnvironmentVariable.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyEnvironmentVariable.ps1 @@ -102,7 +102,16 @@ param( Start-ChocolateyProcessAsAdmin "$psArgs" } } else { - Set-EnvironmentVariable -Name $variableName -Value $variableValue -Scope $variableType + try { + Set-EnvironmentVariable -Name $variableName -Value $variableValue -Scope $variableType + } catch { + if (Test-ProcessAdminRights) { + # HKCU:\Environment may not exist, which happens sometimes with Server Core + Set-EnvironmentVariable -Name $variableName -Value $variableValue -Scope Machine + } else { + throw $_.Exception + } + } } Set-Content env:\$variableName $variableValue