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

注意:

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


当前回答

正如Jonathan Leaders在这里提到的,运行提升的命令/脚本来改变“machine”的环境变量是很重要的,但是运行一些提升的命令并不一定要用社区扩展来完成,所以我想在某种程度上修改和扩展JeanT的回答,即使脚本本身没有运行提升,也可以改变机器变量:

function Set-Path ([string]$newPath, [bool]$permanent=$false, [bool]$forMachine=$false )
{
    $Env:Path += ";$newPath"

    $scope = if ($forMachine) { 'Machine' } else { 'User' }

    if ($permanent)
    {
        $command = "[Environment]::SetEnvironmentVariable('PATH', $env:Path, $scope)"
        Start-Process -FilePath powershell.exe -ArgumentList "-noprofile -command $Command" -Verb runas
    }

}

其他回答

我试着优化了SBF和Michael的代码,使其更紧凑。

我依赖于PowerShell的类型强制,它会自动将字符串转换为enum值,所以我没有定义查找字典。

我还取出了根据条件将新路径添加到列表中的块,这样工作只完成一次,并存储在变量中以供重用。

然后,根据$PathContainer参数,它会被永久地应用到Session中。

我们可以将代码块放在函数或ps1文件中,直接从命令提示符调用。我选择了DevEnvAddPath.ps1。

param(
    [Parameter(Position=0,Mandatory=$true)][String]$PathChange,

    [ValidateSet('Machine', 'User', 'Session')]
    [Parameter(Position=1,Mandatory=$false)][String]$PathContainer='Session',
    [Parameter(Position=2,Mandatory=$false)][Boolean]$PathPrepend=$false
)

[String]$ConstructedEnvPath = switch ($PathContainer) { "Session"{${env:Path};} default{[Environment]::GetEnvironmentVariable('Path', $containerType);} };
$PathPersisted = $ConstructedEnvPath -split ';';

if ($PathPersisted -notcontains $PathChange) {
    $PathPersisted = $(switch ($PathPrepend) { $true{,$PathChange + $PathPersisted;} default{$PathPersisted + $PathChange;} }) | Where-Object { $_ };

    $ConstructedEnvPath = $PathPersisted -join ";";
}

if ($PathContainer -ne 'Session') 
{
    # Save permanently to Machine, User
    [Environment]::SetEnvironmentVariable("Path", $ConstructedEnvPath, $PathContainer);
}

# Update the current session
${env:Path} = $ConstructedEnvPath;

我对DevEnvRemovePath.ps1做了类似的事情。

param(
    [Parameter(Position=0,Mandatory=$true)][String]$PathChange,

    [ValidateSet('Machine', 'User', 'Session')]
    [Parameter(Position=1,Mandatory=$false)][String]$PathContainer='Session'
)

[String]$ConstructedEnvPath = switch ($PathContainer) { "Session"{${env:Path};} default{[Environment]::GetEnvironmentVariable('Path', $containerType);} };
$PathPersisted = $ConstructedEnvPath -split ';';

if ($PathPersisted -contains $PathChange) {
    $PathPersisted = $PathPersisted | Where-Object { $_ -ne $PathChange };

    $ConstructedEnvPath = $PathPersisted -join ";";
}

if ($PathContainer -ne 'Session') 
{
    # Save permanently to Machine, User
    [Environment]::SetEnvironmentVariable("Path", $ConstructedEnvPath, $PathContainer);
}

# Update the current session
${env:Path} = $ConstructedEnvPath;

到目前为止,它们似乎是有效的。

大多数答案都没有涉及UAC。这涵盖了UAC问题。

首先通过http://chocolatey.org/安装PowerShell Community Extensions: choco install pscx(您可能需要重新启动shell环境)。

然后启用pscx

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser #allows scripts to run from the interwebs, such as pcsx

然后使用Invoke-Elevated

Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR

需要明确的是,20世纪90年代的Windows方式,单击开始,右键单击这台PC,选择属性,然后选择高级系统设置,然后在弹出的对话框中,选择环境变量,在列表中双击PATH,然后使用新建,编辑,向上移动和向下移动,这些都仍然可以更改PATH。powershell,其余的Windows会得到你在这里设置的任何东西。

是的,你可以使用这些新方法,但旧方法仍然有效。在基本级别上,所有永久更改方法都是编辑注册表文件的受控方法。

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

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。

就像JeanT的回答一样,我想要一个关于添加路径的抽象。与JeanT的回答不同,我需要它在没有用户交互的情况下运行。我寻找的其他行为:

更新$env:Path,使更改在当前会话中生效 为以后的会话持久化环境变量更改 当相同的路径已经存在时,不添加重复的路径

如果有用的话,这里是:

function Add-EnvPath {
    param(
        [Parameter(Mandatory=$true)]
        [string] $Path,

        [ValidateSet('Machine', 'User', 'Session')]
        [string] $Container = 'Session'
    )

    if ($Container -ne 'Session') {
        $containerMapping = @{
            Machine = [EnvironmentVariableTarget]::Machine
            User = [EnvironmentVariableTarget]::User
        }
        $containerType = $containerMapping[$Container]

        $persistedPaths = [Environment]::GetEnvironmentVariable('Path', $containerType) -split ';'
        if ($persistedPaths -notcontains $Path) {
            $persistedPaths = $persistedPaths + $Path | where { $_ }
            [Environment]::SetEnvironmentVariable('Path', $persistedPaths -join ';', $containerType)
        }
    }

    $envPaths = $env:Path -split ';'
    if ($envPaths -notcontains $Path) {
        $envPaths = $envPaths + $Path | where { $_ }
        $env:Path = $envPaths -join ';'
    }
}

检查我的要点对应的Remove-EnvPath函数。