我发现设置PATH环境变量只影响旧的命令提示符。PowerShell似乎有不同的环境设置。如何更改PowerShell (v1)的环境变量?

注意:

我希望我的更改是永久性的,这样我就不必每次运行PowerShell时都设置它。PowerShell有配置文件吗?比如Unix上的Bash配置文件?


当前回答

所有建议永久更改的答案都有相同的问题:它们破坏了路径注册表值。

SetEnvironmentVariable将REG_EXPAND_SZ值%SystemRoot%\system32转换为c:\ windows \system32的REG_SZ值。

路径中的任何其他变量也会丢失。使用%myNewPath%添加新的将不再工作。

这里有一个脚本Set-PathVariable。我用来解决这个问题的ps1:

 [CmdletBinding(SupportsShouldProcess=$true)]
 param(
     [parameter(Mandatory=$true)]
     [string]$NewLocation)

 Begin
 {

 #requires –runasadministrator

     $regPath = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
     $hklm = [Microsoft.Win32.Registry]::LocalMachine

     Function GetOldPath()
     {
         $regKey = $hklm.OpenSubKey($regPath, $FALSE)
         $envpath = $regKey.GetValue("Path", "", [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
         return $envPath
     }
 }

 Process
 {
     # Win32API error codes
     $ERROR_SUCCESS = 0
     $ERROR_DUP_NAME = 34
     $ERROR_INVALID_DATA = 13

     $NewLocation = $NewLocation.Trim();

     If ($NewLocation -eq "" -or $NewLocation -eq $null)
     {
         Exit $ERROR_INVALID_DATA
     }

     [string]$oldPath = GetOldPath
     Write-Verbose "Old Path: $oldPath"

     # Check whether the new location is already in the path
     $parts = $oldPath.split(";")
     If ($parts -contains $NewLocation)
     {
         Write-Warning "The new location is already in the path"
         Exit $ERROR_DUP_NAME
     }

     # Build the new path, make sure we don't have double semicolons
     $newPath = $oldPath + ";" + $NewLocation
     $newPath = $newPath -replace ";;",""

     if ($pscmdlet.ShouldProcess("%Path%", "Add $NewLocation")){

         # Add to the current session
         $env:path += ";$NewLocation"

         # Save into registry
         $regKey = $hklm.OpenSubKey($regPath, $True)
         $regKey.SetValue("Path", $newPath, [Microsoft.Win32.RegistryValueKind]::ExpandString)
         Write-Output "The operation completed successfully."
     }

     Exit $ERROR_SUCCESS
 }

我在一篇博文中更详细地解释了这个问题。

其他回答

我的建议是:

我已经测试了将C:\oracle\x64\bin永久地添加到环境变量Path中,这工作正常。

$ENV:PATH

第一种方法很简单:

$ENV:PATH=”$ENV:PATH;c:\path\to\folder”

但这种改变不是永久的。$env:path将在关闭PowerShell终端并重新打开时默认恢复到之前的状态。这是因为您在会话级别而不是源级别(即注册表级别)应用了更改。要查看$env:path的全局值,请执行以下操作:

Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH

或者更具体地说:

(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path

现在要改变这一点,首先我们捕获需要修改的原始路径:

$oldpath = (Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path

现在我们定义新的路径应该是什么样的。在本例中,我们添加了一个新文件夹:

$newpath = “$oldpath;c:\path\to\folder”

注意:请确保$newpath看起来是您想要的样子。如果不是,那么你可能会损坏你的操作系统。

现在应用新值:

Set-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH -Value $newPath

现在做最后一次检查,它看起来像你期望的那样:

(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).Path

现在可以重新启动PowerShell终端(甚至重新启动计算机),并看到它不会再次回滚到旧值。

注意路径的顺序可能会改变,所以它是按字母顺序排列的,所以一定要检查整行。为了更简单,你可以使用分号作为分隔符将输出分成行:

($env:path).split(“;”)

如果在PowerShell会话期间,您需要查看或临时修改PATH环境变量,您可以键入以下命令之一:

$env:Path                             # shows the actual content
$env:Path = 'C:\foo;' + $env:Path     # attach to the beginning
$env:Path += ';C:\foo'                # attach to the end

这设置了当前会话的路径,并提示用户永久添加它:

function Set-Path {
    param([string]$x)
    $Env:Path+= ";" +  $x
    Write-Output $Env:Path
    $write = Read-Host 'Set PATH permanently ? (yes|no)'
    if ($write -eq "yes")
    {
        [Environment]::SetEnvironmentVariable("Path",$env:Path, [System.EnvironmentVariableTarget]::User)
        Write-Output 'PATH updated'
    }
}

您可以将此函数添加到您的默认配置文件(Microsoft.PowerShell_profile.ps1),通常位于%USERPROFILE%\Documents\WindowsPowerShell。

打开PowerShell并运行:

[Environment]::SetEnvironmentVariable("PATH", "$ENV:PATH;<path to exe>", "USER")

我发现将C:\vcpkg永久添加到我的PATH env变量中而没有缺点的最简单的解决方案是:

$current_PATH = [Environment]::GetEnvironmentVariable("PATH", "USER");[Environment]::SetEnvironmentVariable("PATH", "$current_PATH;C:\vcpkg;", "USER")

您可以将“USER”更改为“MACHINE”以更改系统环境变量(需要一个管理终端,您可能需要将“Environment”更改为“system .Environment”),甚至可以将“PROCESS”更改为仅更改本地PATH环境变量(不会永久更改)。分别是"USER"=1 "MACHINE"=2和"PROCESS"=0以下是关于这些命令的文档

我发现了另外两个答案,但有很大的缺点,我不建议使用它们。两者都使用SETX,因为它是由PowerShell实现的,以永久地改变env变量。这些命令的缺点是,你将复制你的系统路径到你的区域路径,你需要PowerShell来使用它们:

setx PATH "$($Env:PATH);C:\vcpkg;"

更长,但允许使用其他env变量:

$($Env:PATH).Split(';') | %{ $str += "$($_.Trim('"'));" }; %{ $str += "C:\vcpkg;" } ; setx PATH $str; %{ $str = "" }