programing

레지스트리에서 Windows PowerShell 세션 환경 변수를 업데이트하는 방법은 무엇입니까?

newnotes 2023. 9. 12. 20:43
반응형

레지스트리에서 Windows PowerShell 세션 환경 변수를 업데이트하는 방법은 무엇입니까?

이것은 간단한 질문일 수도 있지만, 적절한 답을 찾을 수 없었습니다.

현재 Windows PowerShell 세션을 닫지 않고 현재 Windows PowerShell 세션 내에서 환경 변수를 업데이트하려면 어떻게 해야 합니까?

지금까지, 예를 들어 내가 수정할 때.PATHControl Panel > System의 환경 변수, 현재 세션을 닫고 새 세션을 열어 변수를 새로 고치거나 발행해야 합니다.SetEnviromentVariable번거로운 일입니다.

저는 리눅스계에서 왔습니다. 그래서 저는 다음과 같은 것을 찾고 있습니다.source지휘.

이런 일 때문에 등록부에 쓰레기통 다이빙을 하러 갈 필요는 없습니다.

foreach($level in "Machine","User") {
   [Environment]::GetEnvironmentVariables($level)
}

PATH 변수를 올바르게 작동시키려면 해당 변수를 특별하게 처리해야 합니다(즉, (잠재적으로) 새로운 것을 이미 가지고 있는 것과 연결하고, 무엇을 제거해야 하는지 확실히 말할 수 없기 때문에 아무것도 잃지 않아야 합니다).

foreach($level in "Machine","User") {
   [Environment]::GetEnvironmentVariables($level).GetEnumerator() | % {
      # For Path variables, append the new values, if they're not already in there
      if($_.Name -match 'Path$') { 
         $_.Value = ($((Get-Content "Env:$($_.Name)") + ";$($_.Value)") -split ';' | Select -unique) -join ';'
      }
      $_
   } | Set-Content -Path { "Env:$($_.Name)" }
}

Set-Content는 실제로 프로세스 환경에서 다음과 같은 작업을 수행하는 것과 같이 변수를 설정합니다.$env:Temp = Convert-Path ~\AppData\Local\Temp

프로세스 시작 시 환경이 채워지므로 프로세스를 다시 시작해야 합니다.

레지스트리에서 읽어 환경을 업데이트할 수 있습니다.아마도 다음과 같은 스크립트를 사용할 것입니다.

function Update-Environment {
    $locations = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
                 'HKCU:\Environment'

    $locations | ForEach-Object {
        $k = Get-Item $_
        $k.GetValueNames() | ForEach-Object {
            $name  = $_
            $value = $k.GetValue($_)

            if ($userLocation -and $name -ieq 'PATH') {
                Env:\Path += ";$value"
            } else {
                Set-Item -Path Env:\$name -Value $value
            }
        }

        $userLocation = $true
    }
}

(테스트되지 않음)

이것은 오래된 질문이지만 초콜릿을 사용하면 핸디 명령어도 설치되어 저는 잘 작동합니다.

현재 PowerShell 세션에 대해서만 경로를 업데이트하려면 다음 작업을 수행합니다.

$env:Path += ";<new path>"

PATH env 변수가 새 PowerShell 세션 전반에 걸쳐 지속되도록 업데이트해야 하는 경우 다음을 사용합니다.

[Environment]::SetEnvironmentVariable("PATH", $env:Path + ";<new path>", 'User')

모든 사용자의 경로를 변경하려면 '사용자'를 '기계'로 변경합니다.

@Joey 답변 감사합니다 (정확하게 표시하였습니다 :) 참고로, 그 순간 레지스트리에 따라 모든 변수를 새로 고치고 싶은 것을 감안하여 if-else 절을 없앴습니다.

레지스트리 변수 위치를 다시 확인해봤는데, 환경 변수는 레지스트리에 저장되어 있는 곳이 어디인가요?

사용된 스니펫은 단지 완성도를 위해 여기에 있습니다.

function Update-Environment {   
    $locations = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
                 'HKCU:\Environment'

    $locations | ForEach-Object {   
        $k = Get-Item $_
        $k.GetValueNames() | ForEach-Object {
            $name  = $_
            $value = $k.GetValue($_)
            Set-Item -Path Env:\$name -Value $value
        }
    }
}

유감스럽게도 다른 답변들은 몇 가지 중요한 세부사항들이 빠져있습니다.PSModulePath에는 PowerShell에서 환경 변수를 업데이트할 때 고려해야 할 몇 가지 특수 처리 기능이 있습니다.변수를 추가, 수정 또는 제거할 수도 있습니다.그리고 경로 환경 변수를 고려해야 합니다.

설상가상으로, 이 작업을 수행할 때 어떤 제품/호스트에 있는지에 따라 해당 제품은 고려해야 할 특별한 환경 변수 처리가 있을 수 있으며, Path 환경 변수(여러 값을 포함하는 것, 반콜론 구분)가 실제로 이름의 일부로 "Path"를 포함하기를 바라는 것 외에도 m.(물론 이것이 Windows가 내부적으로 환경 변수를 처리하는 방식이 아니라면, 저는 그렇게까지 큰 문제를 해결하지 않았습니다.)

현재 PowerShell 세션에서 환경 변수를 다시 시작하지 않고도 제대로 업데이트할 수 있을 것으로 생각되는 것과 거의 유사한 스크립트는 다음과 같습니다.

# Get all environment variables for the current Process, as well as System and User environment variable values
$processValues = [Environment]::GetEnvironmentVariables('Process')
$machineValues = [Environment]::GetEnvironmentVariables('Machine')
$userValues    = [Environment]::GetEnvironmentVariables('User')
# Identify the entire list of environment variable names first
$envVarNames = ($machineValues.Keys + $userValues.Keys + 'PSModulePath') | Sort-Object | Select-Object -Unique
# Now process all of those keys, updating what exists and adding what is new
foreach ($envVarName in $envVarNames) {
    if ($envVarName -eq 'PSModulePath') {
        $pieces = @()
        if ($PSVersionTable.PSVersion -ge [System.Version]'4.0') {
            $pieces += Join-Path -Path ${env:ProgramFiles} -ChildPath 'WindowsPowerShell\Modules'
        }
        if (-not $userValues.ContainsKey($envVarName)) {
            $pieces += Join-Path -Path ([Environment]::GetFolderPath('Documents')) -ChildPath 'WindowsPowerShell\Modules'
        } else {
            $pieces += $userValues[$envVarName] -split ';'
        }
        if ($machineValues.ContainsKey($envVarName)) {
            $pieces += $machineValues[$envVarName] -split ';'
        }
        [Environment]::SetEnvironmentVariable($envVarName,($pieces -join ';'),'Process')
    } elseif ($envVarName -match 'path') {
        $pieces = @()
        if ($userValues.ContainsKey($envVarName)) {
            $pieces += $userValues[$envVarName] -split ';'
        }
        if ($machineValues.ContainsKey($envVarName)) {
            $pieces += $machineValues[$envVarName] -split ';'
        }
        [Environment]::SetEnvironmentVariable($envVarName,($pieces -join ';'),'Process')
    } elseif ($userValues.ContainsKey($envVarName)) {
        [Environment]::SetEnvironmentVariable($envVarName,$userValue[$envVarName],'Process')
    } elseif ($machineValues.ContainsKey($envVarName)) {
        [Environment]::SetEnvironmentVariable($envVarName,$machineValue[$envVarName],'Process')
    }
}
# Lastly remove the environment variables that no longer exist
foreach ($envVarName in $processValues.Keys | Where-Object {$envVarNames -notcontains $_}) {
    Remove-Item -LiteralPath "env:${envVarName}"
}

원칙은 건전하지만 이 분야에서 제가 과거에 수행한 작업에 기반을 두고 있다는 점에 유의하십시오.

언급URL : https://stackoverflow.com/questions/14381650/how-to-update-windows-powershell-session-environment-variables-from-registry

반응형