Configurar a variável de localização PowerShell do Windows

descobri que a definição da variável de ambiente PATH afecta apenas a linha de comandos antiga. PowerShell parece ter diferentes configurações de ambiente. Como posso alterar as variáveis de ambiente para PowerShell (v1)?

Nota:

Quero tornar as minhas mudanças permanentes, para não ter de As definir sempre que dirijo o PowerShell. O PowerShell tem um ficheiro de perfil? Algo como o perfil Bash no Unix?

Author: Peter Mortensen, 2009-04-03

12 answers

Mudar as variáveis de ambiente reais pode ser feito por usando a informação env: namespace / drive. Por exemplo, isto o código irá actualizar a variável de ambiente path:

$env:Path = "SomeRandomPath";

Existem maneiras de tornar as configurações do ambiente permanentes, mas se só os estás a usar a partir de PowerShell, provavelmente é muito melhor para usar o seu perfil para iniciar o definicao. No arranque, o PowerShell irá executar qualquer . ps1 ficheiros que encontra na pasta WindowsPowerShell sob A minha pasta de documentos. Normalmente tem um perfil . ps1 o ficheiro já está aí. O caminho no meu computador é

c:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
 313
Author: JaredPar, 2017-10-08 07:53:38

Se, algum tempo durante uma sessão PowerShell, você precisa de modificar a variável de ambiente PATH temporariamente, você poderá faça assim:

$env:Path += ";C:\Program Files\GnuWin32\bin"
 541
Author: mloskot, 2017-06-18 10:57:14

Também pode modificar permanentemente as variáveis de ambiente do utilizador/sistema (ou seja, será persistente nos reiniciamentos da shell) com o seguinte

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

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

### from comments ###
### Usage from comments - Add to the system environment variable ###
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", [EnvironmentVariableTarget]::Machine)
 184
Author: hoge, 2015-11-16 14:25:54

Do prompt PowerShell:

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

Deve então ver o texto:

SUCCESS: Specified value was saved.

Reinicie a sua sessão, e a variável estará disponível. setx também pode ser usado para definir variáveis arbitrárias. Tipo setx /? na prompt para documentação.

Antes de interferir com o seu caminho desta forma, certifique-se de que guarda uma cópia do seu caminho existente, fazendo $env:path >> a.out numa linha de comando PowerShell.

 44
Author: tjb, 2013-09-10 13:07:41

Embora a resposta aceite funcione no sentido de que a variável path é permanentemente actualizada a partir do contexto do PowerShell, não actualiza a variável de ambiente armazenada no registo do windows. Para conseguir isso você pode obviamente usar PowerShell também:

$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

Mais informações aqui: http://blogs.technet.com/b/heyscriptingguy/archive/2011/07/23/use-powershell-to-modify-your-environmental-path.aspx

Se usares a comunidade PowerShell Extensões, o comando apropriado para adicionar uma localização à localização da variável de ambiente é:

Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
 13
Author: gijswijs, 2014-12-17 20:06:35
Como a resposta de JeanT, eu queria uma abstração em torno de adicionar ao caminho. Ao contrário da resposta do JeanT, precisava que funcionasse sem interacção com o utilizador. Outro comportamento que eu procurava:
  • actualizações $env:Path de modo que a alteração faça efeito na sessão actual
  • persiste a variável de ambiente mudar para as sessões futuras
  • não adiciona um caminho duplicado quando o mesmo caminho já existe
Caso seja útil, aqui está:
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 ';'
    }
}

Verifique fora o meu gist para a função Remove-EnvPath correspondente.

 13
Author: Michael Kropat, 2017-05-23 12:26:27

Isto define a localização da sessão actual e pede ao utilizador para a adicionar permanentemente:

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'
    }
}

Pode adicionar esta função ao seu perfil predefinido, (Microsoft.PowerShell_profile.ps1), normalmente localizado em %USERPROFILE%\Documents\WindowsPowerShell.

 8
Author: JeanT, 2017-10-08 07:56:54
Todas as respostas que sugerem uma mudança permanente têm o mesmo problema: quebram o valor do registro do canal horário.

SetEnvironmentVariable transforma o valor REG_EXPAND_SZ %SystemRoot%\system32 num valor REG_SZ de C:\Windows\system32.

Todas as outras variáveis no caminho também estão perdidas. Adicionar novos usando %myNewPath% não vai funcionar mais.

Aqui está um script Set-PathVariable.ps1 que eu uso para resolver este problema:

 [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
 }

Eu explico o problema mais detalhadamente em um post no blog .

 8
Author: Peter Hahndorf, 2017-10-08 08:00:22

Como Jonathan Líderes mencionado aqui, é importante executar o comando/script elevados para ser capaz de alterar variáveis de ambiente para 'máquina', mas a execução de alguns comandos elevada, não tem que ser feito com a Comunidade Extensões, então eu gostaria de modificar e estender JeanT do resposta em uma forma, que a máquina de troca de variáveis também pode ser realizada, mesmo se o script não é executado com privilégios elevados:

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
    }

}
 4
Author: Mehrdad Mirreza, 2017-08-25 07:04:47

A maioria das respostas não se dirigem à UAC. Trata-se de questões da UAC.

Primeiro instalar extensões da Comunidade PowerShell: choco install pscx via http://chocolatey.org/ (poderá ter de reiniciar o seu ambiente shell).

Depois activar o 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
 4
Author: Jonathan, 2017-10-08 07:55:53

Construindo sobre a resposta de Michael Kropat adicionei um parâmetro para preparar o novo caminho para a variável existente PATHe uma verificação para evitar a adição de um caminho não existente:

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 ';'
            }
        }
    }
}
 1
Author: SBF, 2018-02-05 14:24:02
A MINHA SUGESTÃO É ESTA. eu testei isto para adicionar C:\oracle\x64\bin para o caminho permanentemente e isso funciona bem.
$ENV:PATH

A primeira maneira é simplesmente fazer:

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

Mas esta mudança não é permanente, a $env: path irá voltar ao que era antes, assim que fechar o seu terminal powershell e reabri-lo de novo. Isso porque você aplicou a mudança no nível de sessão e não no nível de fonte (que é o nível de registro). Para ver o valor global de $env: path, do:

Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH

Ou, mais especificamente:

(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path
Agora para mudar isso, primeiro capturamos o caminho original que precisa ser modificado:
$oldpath = (Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path

Agora definimos como deve ser o novo caminho, neste caso estamos a adicionar uma nova pasta:

$newpath = “$oldpath;c:\path\to\folder”
Nota: Certifique-se de que o newpath $parece como você quer que pareça, se não, então você pode danificar o seu SO.

Agora aplica o novo valor:

Set-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH -Value $newPath
Agora faça uma última verificação de que parece como você espere:
Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Contro
l\Session Manager\Environment’ -Name PATH).Path

Agora pode reiniciar o seu terminal powershell (ou até mesmo reiniciar a máquina) e ver se não volta para o seu valor antigo novamente. Observe que a ordenação dos caminhos pode mudar de modo que seja em ordem alfabética, por isso certifique-se de verificar toda a linha, para facilitar, você pode dividir o resultado em linhas usando o ponto-e-vírgula como um delímetro:

($env:path).split(“;”)
 0
Author: ali Darabi, 2018-03-20 09:57:46