Configuración de la variable de ruta de Windows PowerShell


He descubierto que establecer la variable de entorno PATH solo afecta al símbolo del sistema antiguo. PowerShell parece tener diferentes configuraciones de entorno. ¿Cómo cambio las variables de entorno de PowerShell (v1)?

Nota:

Quiero que mis cambios sean permanentes, por lo que no tengo que configurarlos cada vez que corro PowerShell. ¿PowerShell tiene un archivo de perfil? ¿Algo como el perfil Bash en Unix?

Author: Peter Mortensen, 2009-04-03

12 answers

Cambiar las variables de entorno reales se puede hacer por usando la información env: namespace / drive. Por ejemplo, esto code actualizará la variable de entorno path:

$env:Path = "SomeRandomPath";

Hay formas de hacer que la configuración del entorno sea permanente, pero si solo las usas desde PowerShell, probablemente sea mucho mejor utilizar su perfil para iniciar el configuración. Al iniciar, PowerShell ejecutará cualquier . ps1 archivos que encuentra en el directorio WindowsPowerShell bajo Mi carpeta de documentos. Normalmente tener un perfil . ps1 el archivo ya está ahí. La ruta en mi computadora es

c:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
 313
Author: JaredPar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-08 07:53:38

Si, en algún momento durante una sesión de PowerShell, necesita modificar temporalmente la variable de entorno PATH, puede hazlo de esta manera:

$env:Path += ";C:\Program Files\GnuWin32\bin"
 541
Author: mloskot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-18 10:57:14

También puede modificar las variables de entorno de usuario/sistema de forma permanente (es decir, serán persistentes en los reinicios del shell) con la siguiente

### 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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-16 14:25:54

Desde el símbolo del sistema de PowerShell:

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

Entonces deberías ver el texto:

SUCCESS: Specified value was saved.

Reinicie su sesión y la variable estará disponible. setx también se puede usar para establecer variables arbitrarias. Escriba setx /? en la solicitud de documentación.

Antes de jugar con la ruta de acceso de esta manera, asegúrese de guardar una copia de la ruta de acceso existente haciendo $env:path >> a.out en un símbolo del sistema de PowerShell.

 44
Author: tjb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-10 13:07:41

Aunque la respuesta aceptada actual funciona en el sentido de que la variable path se actualiza permanentemente desde el contexto de PowerShell, en realidad no actualiza la variable de entorno almacenada en el registro de Windows. Para lograrlo, obviamente también puede usar 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

Más información aquí: http://blogs.technet.com/b/heyscriptingguy/archive/2011/07/23/use-powershell-to-modify-your-environmental-path.aspx

Si utiliza PowerShell community extensiones, el comando apropiado para agregar una ruta a la variable de entorno path es:

Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
 13
Author: gijswijs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-17 20:06:35

Al igual que la respuesta de JeanT, quería una abstracción alrededor de agregar al camino. A diferencia de la respuesta de JeanT, necesitaba que se ejecutara sin interacción del usuario. Otro comportamiento que estaba buscando:

  • Se actualiza $env:Path para que el cambio surta efecto en la sesión actual
  • Persiste el cambio de la variable de entorno para futuras sesiones
  • No agrega una ruta duplicada cuando la misma ruta ya existe

En caso de que sea útil, aquí 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 ';'
    }
}

Echa un vistazo mi esencia para la función Remove-EnvPath correspondiente.

 13
Author: Michael Kropat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:27

Esto establece la ruta de acceso para la sesión actual y solicita al usuario que la agregue 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'
    }
}

Puede agregar esta función a su perfil predeterminado, (Microsoft.PowerShell_profile.ps1), generalmente ubicado en %USERPROFILE%\Documents\WindowsPowerShell.

 8
Author: JeanT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-08 07:56:54

Todas las respuestas que sugieren un cambio permanente tienen el mismo problema: rompen el valor del registro de ruta.

SetEnvironmentVariable convierte el valor REG_EXPAND_SZ %SystemRoot%\system32 en un valor REG_SZ de C:\Windows\system32.

Cualquier otra variable en la ruta también se pierde. Agregar nuevos usando %myNewPath% ya no funcionará.

Aquí hay un script Set-PathVariable.ps1 que uso para abordar 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
 }

Explico el problema con más detalle enuna entrada de blog .

 8
Author: Peter Hahndorf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-08 08:00:22

Como Jonathan Leaders mencionó aquí , es importante ejecutar el comando / script elevado para poder cambiar las variables de entorno para 'machine' , pero ejecutar algunos comandos elevados no tiene que hacerse con las Extensiones de la Comunidad, por lo que me gustaría modificar y extender answer de alguna manera, que el cambio de variables de máquina también se puede realizar incluso si el script en sí no se ejecuta elevado:

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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-25 07:04:47

La mayoría de las respuestas no se dirigen a UAC. Esto cubre cuestiones de UAC.

Primero instale las extensiones de la comunidad de PowerShell: choco install pscx a través de http://chocolatey.org / (es posible que tenga que reiniciar su entorno de shell).

Luego habilite pscx

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

Luego use Invoke-Elevated

Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR
 4
Author: Jonathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-08 07:55:53

Basándome en la respuesta de@Michael Kropat agregué un parámetro para anteponer la nueva ruta a la variable PATH existente y una comprobación para evitar la adición de una ruta inexistente:

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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-05 14:24:02

MI SUGERENCIA ES ÉSTA HE PROBADO ESTO PARA AÑADIR C:\oracle\x64\bin para Path permanentemente y esto funciona bien.

$ENV:PATH

La primera forma es simplemente hacer:

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

Pero este cambio no es permanente, $env:path volverá a ser lo que era antes tan pronto como cierre el terminal de powershell y lo vuelva a abrir. Esto se debe a que ha aplicado el cambio en el nivel de sesión y no en el nivel de origen (que es el nivel de registro). Para ver el valor global de env env: path, do:

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

O, más específicamente:

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

Ahora para cambiar esto, primero capturamos la ruta original que necesita ser modificada:

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

Ahora definimos cómo debe ser la nueva ruta, en este caso estamos añadiendo una nueva carpeta:

$newpath = “$oldpath;c:\path\to\folder”

Nota: Asegúrese de que el looks newpath se vea como desea que se vea, si no, podría dañar su sistema operativo.

Ahora aplica el nuevo valor:

Set-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH -Value $newPath

Ahora haga una última comprobación de que se ve como espera it:

Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Contro
l\Session Manager\Environment’ -Name PATH).Path

Ahora puede reiniciar su terminal de powershell (o incluso reiniciar la máquina) y ver que no vuelve a su valor anterior. Tenga en cuenta que el orden de las rutas puede cambiar para que esté en orden alfabético, así que asegúrese de verificar toda la línea, para que sea más fácil, puede dividir la salida en filas utilizando el punto y coma como un delímetro:

($env:path).split(“;”)
 0
Author: ali Darabi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-20 09:57:46