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

注意:

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


当前回答

这些脚本是幂等的(可以运行多次)。 它们更新Windows路径和当前/未来的Powershell会话:

永久添加路径

    $targetDir="c:\bin"
    $oldPath = [System.Environment]::GetEnvironmentVariable("Path","Machine")
    $oldPathArray=($oldPath) -split ';'
    if(-Not($oldPathArray -Contains "$targetDir")) {
        write-host "Adding $targetDir to Machine Path"
        $newPath = "$oldPath;$targetDir" -replace ';+', ';'
        [System.Environment]::SetEnvironmentVariable("Path",$newPath,"Machine")
        $env:Path = [System.Environment]::GetEnvironmentVariable("Path","User"),[System.Environment]::GetEnvironmentVariable("Path","Machine") -join ";"
    }
    write-host "Windows paths:"
    ($env:Path).Replace(';',"`n")

永久删除路径

    $targetDir="c:\bin"
    $oldPath = [System.Environment]::GetEnvironmentVariable("Path","Machine")
    $oldPathArray=($oldPath) -split ';'
    if($oldPathArray -Contains "$targetDir") {
        write-host "Removing $targetDir from Machine path"
        $newPathArray = $oldPathArray | Where-Object { $_ –ne "$targetDir" }
        $newPath = $newPathArray -join ";"
        [System.Environment]::SetEnvironmentVariable("Path",$newPath,"Machine")
        $env:Path = [System.Environment]::GetEnvironmentVariable("Path","User"),[System.Environment]::GetEnvironmentVariable("Path","Machine") -join ";"
    }
    write-host "Windows paths:"
    ($env:Path).Replace(';',"`n")

其他回答

虽然目前接受的答案在某种意义上是路径变量从PowerShell的上下文中被永久更新,但它实际上并不更新存储在Windows注册表中的环境变量。

要实现这一点,你显然也可以使用PowerShell:

$oldPath=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path

$newPath=$oldPath+’;C:\NewFolderToAddToTheList\’

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

更多信息请参见博文《使用PowerShell修改环境路径》

如果您使用PowerShell社区扩展,为环境变量path添加路径的正确命令是:

Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine

警告:在PowerShell提示符中执行$env:path >> a.out保存现有路径的副本,以防出现错误。

PowerShell提示符:

setx PATH "$env:path;\the\directory\to\add" -m

然后你应该看到文本:

SUCCESS: Specified value was saved.

重新启动会话,变量就可用了。Setx也可以用来设置任意变量。输入setx /?在文档提示符处。

有很多附加或覆盖的例子。下面是一个在powershell (Linux, Ubuntu 18.04和pwsh 7.1.3)上预先设置路径的示例

$ENV:PATH = "/home/linuxbrew/.linuxbrew/bin:$ENV:PATH"

我特别添加了linuxbrew (homebrew for linux) bin目录,使其优先于已安装的系统。它帮助我解决了一个问题,虽然这是最有帮助的地方,但它也让我“尝试”。

注意:是Linux的路径分隔符,而在Windows(或者至少是我的Windows)上,你会使用;通常是powershell。

只有将值推入注册表的答案才会影响永久更改(因此这个线程上的大多数答案,包括已接受的答案,不会永久影响Path)。

下面的函数适用于Path / PSModulePath和User / System类型。默认情况下,它还会将新路径添加到当前会话。

function AddTo-Path {
    param ( 
        [string]$PathToAdd,
        [Parameter(Mandatory=$true)][ValidateSet('System','User')][string]$UserType,
        [Parameter(Mandatory=$true)][ValidateSet('Path','PSModulePath')][string]$PathType
    )

    # AddTo-Path "C:\XXX" "PSModulePath" 'System' 
    if ($UserType -eq "System" ) { $RegPropertyLocation = 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' }
    if ($UserType -eq "User"   ) { $RegPropertyLocation = 'HKCU:\Environment' } # also note: Registry::HKEY_LOCAL_MACHINE\ format
    $PathOld = (Get-ItemProperty -Path $RegPropertyLocation -Name $PathType).$PathType
    "`n$UserType $PathType Before:`n$PathOld`n"
    $PathArray = $PathOld -Split ";" -replace "\\+$", ""
    if ($PathArray -notcontains $PathToAdd) {
        "$UserType $PathType Now:"   # ; sleep -Milliseconds 100   # Might need pause to prevent text being after Path output(!)
        $PathNew = "$PathOld;$PathToAdd"
        Set-ItemProperty -Path $RegPropertyLocation -Name $PathType -Value $PathNew
        Get-ItemProperty -Path $RegPropertyLocation -Name $PathType | select -ExpandProperty $PathType
        if ($PathType -eq "Path") { $env:Path += ";$PathToAdd" }                  # Add to Path also for this current session
        if ($PathType -eq "PSModulePath") { $env:PSModulePath += ";$PathToAdd" }  # Add to PSModulePath also for this current session
        "`n$PathToAdd has been added to the $UserType $PathType"
    }
    else {
        "'$PathToAdd' is already in the $UserType $PathType. Nothing to do."
    }
}

# Add "C:\XXX" to User Path (but only if not already present)
AddTo-Path "C:\XXX" "User" "Path"

# Just show the current status by putting an empty path
AddTo-Path "" "User" "Path"

我发现将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 = "" }