2009-04-03 29 views
395

Descubrí que la configuración de la variable de entorno PATH afecta solo al antiguo símbolo del sistema. PowerShell parece tener diferentes configuraciones de entorno. ¿Cómo cambio las variables de entorno para PowerShell (v1)?Configuración de la variable de ruta de Windows PowerShell

Nota:

quiero hacer mis cambios permanentes, por lo que no tiene que establecerlo cada vez que funciono PowerShell. ¿Tiene PowerShell un archivo de perfil? Algo como el perfil de Bash en Unix?

+0

I' Me gustaría tener un perfil central ubicado en un recurso compartido de archivos. La sincronización es un dolor. Crear un perfil de stub con. \\ computer \ share \ path \ Profile.ps1 parece un kludge (prueba Notepad $ Profile). Sería bueno si hubiera una manera de cambiar permanentemente la variable automática $ Profile. –

+4

No, el entorno PATH * does * afecta también al símbolo del sistema de PowerShell. Sin embargo, lo que difiere es que powershell no acepta rutas entre comillas. Solución: elimine todas las comillas adjuntas ('" ') en la variable de entorno de ruta – Nilzor

+1

SI SE ENCUENTRA AQUÍ PARA PS> v1 ... Además del comentario anterior de Nilzor: Use esto para eliminar todos los" caminos "en la variable de entorno PATH para su sesión : '$ ($ Env: PATH) .Split (';') | % {$ str + = "$ ($ _. Trim ('"')); "}; $ Env: PATH = $ str' – d3r3kk

Respuesta

276

Cambiando las variables de entorno reales se puede hacer por usando la información env: namespace/drive. Por ejemplo, este código actualizará la variable de entorno de la ruta:

$env:Path = "SomeRandomPath"; 

Hay maneras de configurar el entorno de permanente, pero si sólo se está utilizando desde PowerShell, es probable que mucho mejor utilizar su perfil para iniciar la configuración . Al inicio, PowerShell ejecutará todos los archivos .ps1 que encuentre en el directorio de WindowsPowerShell bajo carpeta Mis documentos. Normalmente tiene un archivo profile.ps1 que ya está allí. El camino en mi equipo es

c:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1 
+26

$ profile es una variable automática que apunta a su perfil de usuario para todos los hosts de PowerShell. – JasonMArcher

+13

Tenga en cuenta que (split-path $ profile) (para obtener la carpeta contenedora) puede contener varios archivos de perfil: profile.ps1 debe ser cargado por todos los hosts, _profile.ps1 solo por el host especificado. Para PowerShell.exe (host de la consola) , esto es Microsoft.PowerShell_profile.ps1. – Richard

+6

¿Qué sucede si no tengo una carpeta WindowsPowerShell en mis documentos? ¿Debo crear la carpeta y el archivo? ¿Qué debo poner en el archivo si deseo agregar 'C: \ path \ to \ file.ext' a las variables de entorno? EDIT: lo encontré ya. La respuesta es sí, créelo. El archivo debe constar de 1 línea: '$ env: path + =; C: \ path \ to \ file. ext "'. – Lewistrick

485

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

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

@Stefano, puede guardar unas cuantas teclas más con + =: $ env: Ruta + = "; c: \ alguna \ nueva \ ruta" – Kevin

+3

+1 :: Esta línea única es bastante efectiva para las invocaciones basadas en sesiones como con mingw ... IE $ env: PATH + = "; c: \ MinGW \ msys \ 1.0 \ bin"^{alguna mingw bin ...} –

+1

y cómo elimino una ruta? – becko

162

Puede también modifique variables de entorno de usuario/sistema de forma permanente (es decir, será persistente en reinicios de shell) con los siguientes

### 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) 
+11

Esto es permanente, ¿verdad? –

+3

Esto es muy útil para sistemas de acceso restringido. – h0tw1r3

+7

@AndresRiofrio, sí, esto es permanente. Uso: '[Entorno] :: SetEnvironmentVariable (" Ruta ", $ env: Ruta +"; C: \ bin ", [EnvironmentVariableTartget :: Machine)' ** No verá el resultado de este cambio hasta que comience una nueva sesión de PowerShell. ** Es decir, si inspecciona $ env: Path inmediatamente después de ejecutar este comando, verá qué $ env: Path estaba antes del comando. Para actualizar, cerrar y abrir el shell o iniciar una nueva sesión. – FLGMwt

39

Desde PowerShell p el pronto:

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

continuación, debería ver el texto:

SUCCESS: Specified value was saved. 

reinicie la sesión, y la variable estará disponible. setx también se puede usar para establecer variables arbitrarias. Escriba setx /? en el indicador de documentación.

Antes de jugar con su ruta de esta manera, asegúrese de guardar una copia de la ruta existente haciendo $env:path >> a.out en un indicador de PowerShell.

+1

Parece que solo funciona cuando se ejecuta como administrador y, a partir de ese momento, solo tiene efecto para las consolas PowerShell "en ejecución como administrador", que no ejecutan regularmente las que se ejecutan. – matanster

+1

Aquí hay algunos [documentación oficial de Microsoft para Setx] (http://technet.microsoft.com/en-us/library/cc755104 (v = ws.10) .aspx). –

+9

Ouch - acaba de ser golpeado por el límite de 1024 caracteres de setx; Afortunadamente seguí el consejo de registrar el valor existente de $ end: Path. Algo a tener en cuenta: http://superuser.com/questions/387619/overcoming-the-1024-character-limit-with-setx – Jonno

11

Aunque la respuesta aceptada actual funciona en el sentido de que la variable de ruta se actualiza de forma permanente desde el contexto de PowerShell, en realidad no actualiza la variable de entorno almacenada en el registro de Windows. Para lograr que, obviamente, puede utilizar PowerShell así:

$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 extensiones de la comunidad de PowerShell, el comando adecuado para añadir una ruta a la ruta variable de entorno es:

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

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

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

Después habilite pscx

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

A continuación, utilice Invoke-Elevated

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

Esto prepara el camino para la sesión actual y solicita al usuario añadir de forma permanente:

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 agregue esta función a su perfil predeterminado, (Microsoft.PowerShell_profile.ps1), us ual ubicado en %USERPROFILE%\Documents\WindowsPowerShell.

10

Como JeanT's answer, quería una abstracción para agregar a la ruta. A diferencia de la respuesta de JeanT, necesitaba que se ejecutara sin interacción del usuario. Otro comportamiento que estaba buscando:

  • Actualizaciones $env:Path por lo que el cambio entre en vigor en la sesión actual
  • Persiste el cambio de variable de entorno para las futuras sesiones
  • No aporta una trayectoria duplicada cuando el mismo camino 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 ';' 
    } 
} 

Consulte my gist para la función correspondiente Remove-EnvPath.

+0

Realmente me gusta este. Buen trabajo. – stevethethread

3

Como Jonathan Leaders mencionado here, es importante para ejecutar el comando/script elevado a ser capaz de cambiar las variables de entorno para 'máquina', pero la ejecución de algunos comandos elevados no tiene que ser hecho con las extensiones de la Comunidad, así que me gustaría modificar y ampliar JeanT'sanswer de una manera, que el cambio de variables de la máquina también se puede realizar incluso si el propio script 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 
    } 

} 
5

Todas las respuestas que sugieren un cambio permanente tienen la 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.

También se pierden otras variables en la ruta. Agregar nuevos utilizando %myNewPath% ya no funcionará.

Aquí es un script Set-PathVariable.ps1 que utilizo para hacer frente a 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 en a blog post.

-1

MI SUGERENCIA ES ESTE HE PROBADO ESTO PARA AÑADIR C: \ oracle \ x64 \ bin a la ruta de forma permanente y esto funciona bien.

$ ENV: RUTA

La primera manera es simplemente hacer:

$ ENV: PATH =”$ ENV: RUTA; c: \ ruta \ a \ carpeta”

Pero esto el cambio no es permanente, $ env: ruta volverá a ser lo que era antes tan pronto como cierre su terminal powerhell 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: ruta, hacer:

Get-ItemProperty -path ':: Registro HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment' PATH -Nombre

o, más concretamente, :

(Get-ItemProperty -path ':: Registro HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ control \ Session Manager \ Environment' PATH -Nombre) .Path

Ahora que cambiar esto, primero tenemos capturar la ruta original que necesita ser modificado:

$ oldpath = (Get-ItemProperty -path ':: Registro HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment' PATH -Nombre) .Path

Ahora definimos lo que la nueva ruta de acceso debe ser similar, en este caso estamos agregando una nueva carpeta: $ newpath = "$ oldpath; c: \ path \ to \ folder"

Nota: asegúrese de que $ newpath tenga el aspecto que desea que tenga, de lo contrario, podría dañar su sistema operativo.

Ahora aplicar el nuevo valor: RUTA -Nombre

Set-ItemProperty -path ':: Registro HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment' -Valor $ newpath

Ahora lleve a cabo una comprobación final que se ve cómo se espera que:

Get-ItemProperty -path ':: Registro HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Contro l \ Administrador de sesión \ Environment' PATH -Nombre) .Path

Ahora puede reiniciar su terminal powershell (o incluso reiniciar la máquina) y ver que no vuelva 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 marcar toda la línea, para hacerlo más fácil, puede dividir la salida en filas usando el punto y coma como un delímetro:

($ env: ruta).split (“;”)

0

Basándose en @Michael Kropat's respuesta que añade un parámetro al anteponer la nueva ruta de acceso a la existente PATH variable y un cheque para evitar la adición de una trayectoria no 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 ';' 
      } 
     } 
    } 
} 
Cuestiones relacionadas