设置Windows PowerShell环境变量

时间:2009-04-03 17:19:35

标签: windows powershell

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

注意:

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

19 个答案:

答案 0 :(得分:593)

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

$env:Path += ";C:\Program Files\GnuWin32\bin"

答案 1 :(得分:358)

更改实际环境变量可以通过 使用env: namespace / drive信息。例如,这个 代码将更新路径环境变量:

$env:Path = "SomeRandomPath";             (replaces existing path) 
$env:Path += ";SomeRandomPath"            (appends to existing path)

有一些方法可以永久保持环境设置,但是 如果您只是从PowerShell使用它们,那可能就是这样 使用您的个人资料启动更好 设置。在启动时,PowerShell将运行任何 .ps1 它在WindowsPowerShell目录下找到的文件 我的文档文件夹。通常,您有一个 profile.ps1 文件已存在。我的电脑上的路径是

C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1

答案 2 :(得分:214)

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

### Modify a system environment variable ###
[Environment]::SetEnvironmentVariable
     ("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)

### Modify a user environment variable ###
[Environment]::SetEnvironmentVariable
     ("INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User)

### Usage from comments - add to the system environment variable ###
[Environment]::SetEnvironmentVariable(
    "Path",
    [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\bin",
    [EnvironmentVariableTarget]::Machine)

答案 3 :(得分:49)

从PowerShell提示符:

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

然后您应该看到文字:

SUCCESS: Specified value was saved.

重新启动会话,变量将可用。 setx也可用于设置任意变量。在提示文档时输入setx /?

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

答案 4 :(得分:21)

JeanT's answer一样,我想要一个关于添加路径的抽象。与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 ';'
    }
}

查看my gist以查找相应的Remove-EnvPath功能。

答案 5 :(得分:15)

尽管当前接受的答案在路径变量从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

更多信息请参阅博客文章 Use PowerShell to Modify Your Environmental Path

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

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

答案 6 :(得分:9)

所有表明永久性更改的答案都存在同样的问题:它们会破坏路径注册表值。

SetEnvironmentVariableREG_EXPAND_SZ%SystemRoot%\system32转换为REG_SZ C:\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
 }

我在a blog post中更详细地解释了这个问题。

答案 7 :(得分:8)

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

$html = file_get_contents("http://www.dresslink.com/womens-candy-color-basic-coat-slim-suit-jacket-blazer-p-8131.html");

您可以将此功能添加到您的默认个人资料($row['released'] = ($row['released'] == 0) ? 'No' : 'Yes'; $row['sex'] = ($row['sex'] == 0) ? 'Male' : 'Female'; $myArray[] = $row; ),通常位于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' } }

答案 8 :(得分:5)

正如Jonathan Leaders提到here一样,运行命令/脚本以提升能够更改' machine' 的环境变量非常重要,但运行一些提升的命令并不需要使用社区扩展,所以我想以某种方式修改和扩展JeanT's answer,更改机器变量也可以即使脚本本身没有升级也要执行:

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
    }

}

答案 9 :(得分:5)

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

首先通过http://chocolatey.org/安装PowerShell社区扩展程序: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

答案 10 :(得分:4)

@Michael Kropat's回答的基础上,我添加了一个参数来预先添加现有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 ';'
            }
        }
    }
}

答案 11 :(得分:2)

仅将值推入注册表的答案会影响永久更改(因此,该线程上的大多数答案(包括已接受的答案)都不会永久影响 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"

答案 12 :(得分:1)

我的建议就是这一点 我已经测试过将C:\ oracle \ x64 \ bin永久添加到Path,这样可以正常工作。

$ENV:PATH

第一种方法就是:

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

但是这个改变并不是永久性的,$ env:当你关闭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(“;”)

答案 13 :(得分:1)

要清楚,在1990年代的Windows中,单击开始,右键单击此PC ,然后选择属性,然后选择高级系统设置,然后在弹出的对话框中选择环境变量,然后在列表中双击 PATH ,然后使用新建编辑向上移动向下移动仍然可以更改PATH。 Power Shell,Windows的其余部分都可以在这里进行设置。

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

答案 14 :(得分:0)

我尝试优化SBF'sMichael's代码以使其更紧凑。

我依靠PowerShell的类型强制,它会自动将字符串转换为枚举值,因此我没有定义查找字典。

我还根据条件拉出了将新路径添加到列表的代码块,以便一次完成工作并将其存储在变量中以供重复使用。

然后根据$PathContainer参数将其永久或仅应用于会话。

我们可以将代码块放入直接从命令提示符下调用的函数或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;

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

答案 15 :(得分:0)

打开PowerShell并运行:

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

答案 16 :(得分:0)

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

Set-Location Env:

这将带您到Env:>目录。在此目录中:

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

Env:\> Get-ChildItem

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

Env:\> $Env:<variable name>, e.g. $Env:Path

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

Env:\> $Env:<variable name> = "<new-value>", e.g. $Env:Path="C:\Users\"

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

Env:\> remove-item Env:<variable name>, e.g. remove-item Env:SECRET_KEY

此处有更多信息:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables?view=powershell-6

答案 17 :(得分:0)

不要为自己烦恼,想要一个简单的单行解决方案来添加永久环境变量(以升高模式打开powershell):

[Environment]::SetEnvironmentVariable("NewEnvVar", "NewEnvValue", "Machine")

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


如果您要修改/更改

[Environment]::SetEnvironmentVariable("oldEnvVar", "NewEnvValue", "Machine")


以防您要删除/删除

[Environment]::SetEnvironmentVariable("oldEnvVar", "", "Machine")

答案 18 :(得分:0)

很多附加或覆盖的例子。以下是在适用于 Linux、Ubuntu 18.04 和 pwsh 7.1.3

的 powershell 上添加路径的示例
$ENV:PATH = "/home/linuxbrew/.linuxbrew/bin:$ENV:PATH"

我特意添加了 linuxbrew(Linux 自制软件)bin 目录以优先于安装的系统。它帮助解决了我遇到的一个问题,虽然这是最有帮助的地方,但它也让我“尝试”。

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