设置Windows PowerShell路径变量

Vas*_*sil 558 windows powershell

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

注意:

我希望永久更改我的更改,因此每次运行PowerShell时都不必设置它.PowerShell有配置文件吗?像Unix上的Bash配置文件?

mlo*_*kot 606

如果,在PowerShell会话期间的某个时间,您需要临时附加到PATH环境变量,您可以这样做:

$env:Path += ";C:\Program Files\GnuWin32\bin"
Run Code Online (Sandbox Code Playgroud)

  • 如果您需要在标准路径之前调用路径,请将其插入开头`$ env:Path ="C:\ MyPath; $ env:Path"` (11认同)
  • +1 ::这个单行对于基于会话的调用非常有效,就像mingw ... IE $ env:PATH + ="; c:\ MinGW\msys\1.0\bin"^ {some mingw bin ... } (4认同)
  • ****不要忘记附加字符串开头的分号,如@Kevin的评论中所示.这很明显,但如果您只是在代码中复制/粘贴代码并且在现有路径的末尾没有分号,则可能会错过.我会尝试提交一个编辑. (4认同)
  • 以及如何删除路径? (2认同)
  • Becko,要删除路径需要一些代码: $env:PATH = ($env:PATH -split ";" | %{ if($_ -ne "/path_to_remove") { $_ } }) -join ";" (2认同)

Jar*_*Par 409

可以使用该env: namespace / drive信息更改实际环境变量.例如,此代码将更新路径环境变量:

$env:Path = "SomeRandomPath";             (replaces existing path) 
$env:Path += ";SomeRandomPath"            (appends to existing path)
Run Code Online (Sandbox Code Playgroud)

有一些方法可以永久保持环境设置,但如果您只是从PowerShell使用它们,那么使用您的配置文件启动设置可能要好得多.在启动时,PowerShell将运行 它在My Documents文件夹下的WindowsPowerShell目录中找到的任何.ps1文件.通常,您已经有profile.ps1 文件.我的电脑上的路径是

C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
Run Code Online (Sandbox Code Playgroud)

  • $ profile是一个自动变量,指向所有PowerShell主机的用户配置文件. (32认同)
  • 请注意(split-path $ profile)(以获取包含文件夹)可以包含多个配置文件:profile.ps1应由所有主机加载,<host-name> _profile.ps1仅由指定的主机加载.对于PowerShell.exe(控制台主机),这是Microsoft.PowerShell_profile.ps1. (16认同)
  • 小心这样做 - 它会破坏你现有的路径.```$ env:Path ="SomeRandomPath"; ```相反 - 请参阅下面的@mloskot. (15认同)
  • 如果我的文档中没有WindowsPowerShell文件夹怎么办?我应该创建文件夹和文件吗?如果我想将`C:\ path\to\file.ext`添加到环境变量中,我应该在文件中添加什么?编辑:已经找到了.答案是肯定的,创造它.该文件应包含1行:`$ env:path + =; C:\ path\to\file.ext"`. (10认同)
  • @Lewistrick默认情况下,您没有个人资料.我按照这些说明创建了一个:http://www.howtogeek.com/50236/customizing-your-powershell-profile/ (7认同)
  • 我不明白为什么这被认为是一个答案。问题是如何永久更新 PATH,而这并不能做到这一点。这“不是”所提问题的答案。“我想让我的更改永久生效,这样我就不必每次运行 PowerShell 时都进行设置。” 没有得到答复。(我添加了一个影响此线程永久更改的答案)。 (2认同)

小智 238

您还可以使用以下命令永久修改用户/系统环境变量(即,将在shell重新启动时保持持久性):

[Environment]::SetEnvironmentVariable
     ("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)
Run Code Online (Sandbox Code Playgroud)

  • @AndresRiofrio,是的,这是永久性的.用法:`[Environment] :: SetEnvironmentVariable("Path",$ env:Path +"; C:\ bin",[EnvironmentVariableTartget :: Machine)`**在开始新的更改之前,您不会看到此更改的结果powershell session.**也就是说,如果在运行此命令后立即检查$ env:Path,您将看到$ env:Path在命令之前是什么.更新,关闭和打开shell或启动新会话. (13认同)
  • 您可以编写字符串"Machine"或"User"而不是整个.NET枚举.来自[Technet](http://technet.microsoft.com/en-us/library/ff730964.aspx). (9认同)
  • @FLGMwt你有一个拼写错误,正确的是:[Environment] :: SetEnvironmentVariable("Path",$ env:Path +"; C:\ bin",[EnvironmentVariableTarget] :: Machine) (7认同)
  • 这对于受限制的访问系统非常有用. (4认同)
  • 我认为答案也应该用于设置用户变量,例如`[Environment] :: SetEnvironmentVariable("Path",[Environment] :: GetEnvironmentVariable("Path","User")+"; C:\ bin" ,"用户")` (3认同)
  • @ Erutan409 SetEnvironmentVariable可能有三个目标.`[EnvironmentVariableTarget] :: Machine`永久影响每个人的新进程,`[EnvironmentVariableTarget] :: User`永久影响当前用户的新进程,`[EnvironmentVariableTarget] :: Process`,影响当前进程环境只要.您可以将变量设置两次,一次设置为User/Machine,一次设置为Process.这会影响新流程和当前流程的变量.但是,其他当前流程不会受到影响. (2认同)
  • 这对我来说似乎不起作用.我试图在User路径变量中添加一个目录,一切似乎都有效,但在启动一个新的Powershell终端后,`$ env :: PATH`保持不变. (2认同)
  • 我希望您知道以下事实:此答案将破坏您路径中的所有动态(也称为扩展)项目。例如。如果您的环境中具有`GIT_INSTALL_ROOT = c:\ tools \ git`和`PATH = ...;%GIT_INSTALL_ROOT%\ cmd;%GIT_INSTALL_ROOT%\ mingw64 \ bin`,则您将丢失对`GIT_INSTALL_ROOT`变量的所有引用路径,因此它将固定连接到某个固定目录 (2认同)
  • 这是一个很好的解决方案,只需确保连接现有的 `$env:PATH` 不会添加您不想添加的内容。在初始化脚本中修改“PATH”是很常见的,您可能不知道它已针对特定会话进行了更改。例如,Powershell 7.0.2 在会话初始化时将自身添加到“PATH”,因此每次调用“SetEnvironmentVariable()”时,此技术都会添加该临时条目。这只是一个提醒,因为我确实认为这是永久更新“PATH”的正确方法。 (2认同)

tjb*_*tjb 57

从PowerShell提示符:

setx PATH "$env:path;\the\directory\to\add" -m
Run Code Online (Sandbox Code Playgroud)

然后你应该看到文字:

SUCCESS: Specified value was saved.
Run Code Online (Sandbox Code Playgroud)

重新启动会话,变量将可用.setx也可以用来设置任意变量.键入setx /?在提示文档.

在以这种方式弄乱路径之前,请确保通过$env:path >> a.out在PowerShell提示符下保存现有路径的副本.

  • 哎哟 - 刚被setx的1024个字符限制所击中; 谢天谢地,我按照建议记录了$ end:Path的现有值.需要注意的事项:http://superuser.com/questions/387619/overcoming-the-1024-character-limit-with-setx (11认同)
  • 似乎只在"以管理员身份运行"时才起作用,此后仅对"以管理员身份运行"的PowerShell控制台生效,而不是定期运行. (3认同)
  • 为什么不先设置`$ env:PATH`,然后设置`setx / m PATH“ $ env:PATH”`,以使其在本地和全局应用而无需重新启动Shell? (3认同)
  • 好的!尽管 setx 不是本机 cmdlet,但仍然是那些令人讨厌的冗长 .NET Framework 调用的更好且容易被遗忘的替代方案!令人困惑的是,即使是 Powershell 7 仍然没有提供官方 cmdlet 来保存环境变量。什么。感觉像是一个应该与“ls”同等的功能。 (2认同)

Mic*_*pat 25

就像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 ';'
    }
}
Run Code Online (Sandbox Code Playgroud)

查看我的要点以获得相应的Remove-EnvPath功能.


gij*_*ijs 16

虽然当前接受的答案在路径变量从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
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅博客文章使用PowerShell修改您的环境路径

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

Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
Run Code Online (Sandbox Code Playgroud)


Pet*_*orf 9

所有建议永久性更改的答案都有同样的问题:它们打破了路径注册表值.

SetEnvironmentVariableREG_EXPAND_SZ%SystemRoot%\system32 转换为REG_SZC:\Windows\system32.

路径中的任何其他变量也会丢失.添加新的使用%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
 }
Run Code Online (Sandbox Code Playgroud)

我在博客文章中更详细地解释了这个问题.

  • 应该是: $newPath = $newPath -replace ";;",";" ? (2认同)

小智 8

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

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'
    }
}
Run Code Online (Sandbox Code Playgroud)

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


小智 8

我的建议是这样的:

我已经对此进行了测试以永久添加C:\oracle\x64\bin到环境变量中,Path并且效果很好。

$ENV:PATH
Run Code Online (Sandbox Code Playgroud)

第一种方法很简单:

$ENV:PATH=”$ENV:PATH;c:\path\to\folder”
Run Code Online (Sandbox Code Playgroud)

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

Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH
Run Code Online (Sandbox Code Playgroud)

或者更具体地说:

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

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

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

现在我们定义新路径应该是什么样子。在这种情况下,我们将附加一个新文件夹:

$newpath = “$oldpath;c:\path\to\folder”
Run Code Online (Sandbox Code Playgroud)

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

现在应用新值:

Set-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH -Value $newPath
Run Code Online (Sandbox Code Playgroud)

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

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

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

请注意,路径的顺序可能会发生变化,因此按字母顺序排列,因此请确保检查整行。为方便起见,您可以使用分号作为分隔符将输出拆分为多行:

($env:path).split(“;”)
Run Code Online (Sandbox Code Playgroud)


Yor*_*ubs 8

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

以下函数适用于Path/PSModulePathUser/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"
Run Code Online (Sandbox Code Playgroud)


SBF*_*SBF 6

@Michael Kropat的答案的基础上,我添加了一个参数来将新路径添加到现有PATH变量的前面,并添加了一个检查以避免添加不存在的路径:

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

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

        [Parameter(Mandatory=$False)]
        [Switch] $Prepend
    )

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

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

        $envPaths = $env:Path -split ';'
        if ($envPaths -notcontains $Path) {
            if ($Prepend) {
                $envPaths = ,$Path + $envPaths | where { $_ }
                $env:Path = $envPaths -join ';'
            }
            else {
                $envPaths = $envPaths + $Path | where { $_ }
                $env:Path = $envPaths -join ';'
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*rer 6

在 PowerShell 中,可以通过键入以下内容导航到环境变量目录:

Set-Location Env:
Run Code Online (Sandbox Code Playgroud)

这将带您进入 Env:> 目录。从这个目录中:

要查看所有环境变量,请键入:

Env:\> Get-ChildItem
Run Code Online (Sandbox Code Playgroud)

要查看特定的环境变量,请键入:

Env:\> $Env:<variable name>, e.g. $Env:Path
Run Code Online (Sandbox Code Playgroud)

要设置环境变量,请键入:

Env:\> $Env:<variable name> = "<new-value>", e.g. $Env:Path="C:\Users\"
Run Code Online (Sandbox Code Playgroud)

要删除环境变量,请键入:

Env:\> remove-item Env:<variable name>, e.g. remove-item Env:SECRET_KEY
Run Code Online (Sandbox Code Playgroud)

更多信息在关于环境变量中


Jon*_*han 5

大多数答案都没有解决UAC问题.这涵盖了UAC问题.

首先安装PowerShell社区扩展:choco install pscx通过http://chocolatey.org/(您可能必须重新启动shell环境).

然后启用pscx

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser #allows scripts to run from the interwebs, such as pcsx
Run Code Online (Sandbox Code Playgroud)

然后用 Invoke-Elevated

Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR
Run Code Online (Sandbox Code Playgroud)


Meh*_*eza 5

正如Jonathan Leaders提到的那样,重要的是运行命令/脚本以提升能够更改"机器"的环境变量,但运行一些提升的命令不一定要使用社区扩展,所以我想要以某种方式修改和扩展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
    }

}
Run Code Online (Sandbox Code Playgroud)


ash*_*deh 5

不要让自己头疼,想要一个简单的单行解决方案来添加永久环境变量(在提升模式下打开 powershell ):

[Environment]::SetEnvironmentVariable("NewEnvVar", "NewEnvValue", "Machine")
Run Code Online (Sandbox Code Playgroud)

关闭会话并再次打开它以完成任务


如果您想修改/更改

[Environment]::SetEnvironmentVariable("oldEnvVar", "NewEnvValue", "Machine")
Run Code Online (Sandbox Code Playgroud)


如果你想删除/删除

[Environment]::SetEnvironmentVariable("oldEnvVar", "", "Machine")
Run Code Online (Sandbox Code Playgroud)

  • 事实上,所有这些“Setx”和“$Env”答案都让我头疼。这一款很优雅! (6认同)

Mac*_*Mac 5

需要说明的是,1990年代的Windows方式是点击开始,右键点击This PC,选择属性,然后选择高级系统设置,然后在弹出的对话框中选择环境变量,在列表中双击在PATH 上,然后使用NewEditMove UpMove Down仍然可以更改 PATH。Power shell 和 Windows 的其余部分获得您在此处设置的任何内容。

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