Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
设置Windows PowerShell环境变量_Windows_Powershell - Fatal编程技术网

设置Windows PowerShell环境变量

设置Windows PowerShell环境变量,windows,powershell,Windows,Powershell,我发现设置PATH环境变量只会影响旧的命令提示符。PowerShell似乎有不同的环境设置。如何更改PowerShell(v1)的环境变量 注: 我希望将更改永久化,因此不必每次运行PowerShell时都进行设置。PowerShell是否有配置文件?类似于Unix上的Bash profile?更改实际环境变量可以通过 使用env:namespace/drive信息。比如说这个, 代码将更新path环境变量: $env:Path=“SomeRandomPath”;(替换现有路径) $env:Pa

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

注:


我希望将更改永久化,因此不必每次运行PowerShell时都进行设置。PowerShell是否有配置文件?类似于Unix上的Bash profile?

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

$env:Path=“SomeRandomPath”;(替换现有路径)
$env:Path+=“SomeRandomPath”(附加到现有路径)
有一些方法可以使环境设置永久化,但是 如果您仅从PowerShell使用它们,则可能 使用您的个人资料来启动 设置。启动时,PowerShell将运行任何.ps1 它在下的
WindowsPowerShell
目录中找到的文件 我的文档文件夹。通常您有一个profile.ps1 文件已经在那里了。我计算机上的路径是

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

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

$env:Path+=“C:\Program Files\GnuWin32\bin”

您还可以通过以下操作永久地修改用户/系统环境变量(即,在shell重新启动时将保持不变):

修改系统环境变量

[Environment]::SetEnvironmentVariable
     ("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)
修改用户环境变量

[Environment]::SetEnvironmentVariable
     ("INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User)
[Environment]::SetEnvironmentVariable(
    "Path",
    [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\bin",
    [EnvironmentVariableTarget]::Machine)
注释中的用法-添加到系统环境变量

[Environment]::SetEnvironmentVariable
     ("INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User)
[Environment]::SetEnvironmentVariable(
    "Path",
    [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\bin",
    [EnvironmentVariableTarget]::Machine)
如果您不想写入类型,也可以使用基于字符串的解决方案

[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", "Machine")

从PowerShell提示符:

setx PATH "$env:path;\the\directory\to\add" -m
然后,您将看到以下文本:

SUCCESS: Specified value was saved.
重新启动会话,变量将可用
setx
也可用于设置任意变量。在提示输入文档时键入
setx/?


在以这种方式破坏路径之前,请确保通过在PowerShell提示符中执行a.out,保存现有路径的副本。

尽管当前接受的答案可以从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社区扩展,则向环境变量path添加路径的正确命令为:

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

大多数答案都没有提到。这包括UAC问题

首先安装PowerShell社区扩展:
choco安装pscx
via(您可能需要重新启动shell环境)

然后启用pscx

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser #allows scripts to run from the interwebs, such as pcsx
然后使用
调用提升的

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

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

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\u profile.ps1
),通常位于
%USERPROFILE%\Documents\WindowsPowerShell
类似于,我想要一个关于添加到路径的抽象。与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
函数。

如前所述,运行提升的命令/脚本以能够更改'machine'的环境变量非常重要,但运行一些提升的命令不必通过社区扩展来完成,因此,我想在某种程度上进行修改和扩展,即使脚本本身没有运行,也可以执行更改机器变量:

函数集路径([string]$newPath,[bool]$permanent=$false,[bool]$forMachine=$false)
{
$Env:Path+=“;$newPath”
$scope=if($forMachine){'Machine'}else{'User'}
若有(永久性)
{
$command=“[Environment]::SetEnvironmentVariable('PATH',$env:PATH,$scope)”
启动进程-FilePath powershell.exe-ArgumentList“-noprofile-command$command”-动词runas
}
}

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

SetEnvironmentVariable
REG\u EXPAND\u SZ
%SystemRoot%\system32
转换为
C:\Windows\system32
REG\u 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
的外观符合您的要求。如果不是,那你就可以毁了
($env:path).split(“;”)
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 ';'
            }
        }
    }
}
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;
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;
[Environment]::SetEnvironmentVariable("PATH", "$ENV:PATH;<path to exe>", "USER")
Set-Location 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
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"
[Environment]::SetEnvironmentVariable("NewEnvVar", "NewEnvValue", "Machine")
[Environment]::SetEnvironmentVariable("oldEnvVar", "NewEnvValue", "Machine")
[Environment]::SetEnvironmentVariable("oldEnvVar", "", "Machine")
$ENV:PATH = "/home/linuxbrew/.linuxbrew/bin:$ENV:PATH"