Définition de la variable de chemin Windows PowerShell

J'ai découvert que la définition de la variable D'environnement PATH n'affecte que l'ancienne invite de commande. PowerShell semble avoir des paramètres d'environnement différents. Comment modifier les variables D'environnement pour PowerShell (v1)?

Remarque:

Je veux rendre mes modifications permanentes, donc je n'ai pas besoin de les définir chaque fois que je lance PowerShell. PowerShell a-t-il un fichier de profil? Quelque chose comme profil Bash sur Unix?

444
demandé sur Peter Mortensen 2009-04-03 21:19:35

12 réponses

Changer les variables d'environnement réelles peut être fait par utilisation des informations env: namespace / drive. Par exemple, ce le code mettra à jour la variable d'environnement path:

$env:Path = "SomeRandomPath";

Il existe des moyens de rendre les paramètres d'environnement permanents, mais si vous ne les utilisez que de PowerShell, c'est probablement beaucoup mieux utiliser votre profil pour lancer le paramètre. Au démarrage, PowerShell exécutera any . ps1 fichiers qu'il trouve dans le répertoire WindowsPowerShell sous Dossier Mes Documents. En général, vous avoir un profil . ps1 fichier déjà là. Le chemin sur mon ordinateur est

c:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
313
répondu JaredPar 2017-10-08 07:53:38

Si, pendant une session PowerShell, vous devez modifiez temporairement la variable D'environnement PATH, vous pouvez faire de cette façon:

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

Vous pouvez également modifier de façon permanente les variables d'environnement utilisateur/système (c'est-à-dire qu'elles seront persistantes entre les redémarrages du shell) avec

### 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
répondu hoge 2015-11-16 14:25:54

À partir de L'invite PowerShell:

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

Vous devriez alors voir le texte:

SUCCESS: Specified value was saved.

Redémarrez votre session, et la variable sera disponible. setx peut également être utilisé pour définir des variables arbitraires. Tapez setx /? à l'invite de documentation.

Avant de jouer avec votre chemin de cette façon, assurez-vous d'enregistrer une copie de votre chemin existant en faisant $env:path >> a.out dans une invite PowerShell.

44
répondu tjb 2013-09-10 13:07:41

Bien que la réponse acceptée actuelle fonctionne dans le sens où la variable path est mise à jour en permanence à partir du contexte de PowerShell, elle ne met pas réellement à jour la variable d'environnement stockée dans le registre windows. Pour y parvenir, vous pouvez évidemment utiliser PowerShell aussi bien:

$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

Plus d'infos ici: http://blogs.technet.com/b/heyscriptingguy/archive/2011/07/23/use-powershell-to-modify-your-environmental-path.aspx

Si vous utilisez la communauté PowerShell extensions, la commande appropriée pour ajouter un chemin à la variable d'environnement path est:

Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
13
répondu gijswijs 2014-12-17 20:06:35

Comme la réponse de JeanT , je voulais une abstraction autour de l'ajout au chemin. Contrairement à la réponse de JeanT, j'en avais besoin pour fonctionner sans interaction de l'utilisateur. Autre comportement que je cherchais:

  • met à jour $env:Path de sorte que la modification prend effet dans la session en cours
  • persiste le changement de variable d'environnement pour les sessions futures
  • n'ajoute pas de chemin en double lorsque le même chemin existe déjà

Dans le cas où c'est utile, le voici:

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

Vérifier mon essentiel pour la fonction Remove-EnvPath correspondante.

13
répondu Michael Kropat 2017-05-23 12:26:27

Cela définit le chemin de la session en cours et invite l'utilisateur à l'ajouter définitivement:

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

, Vous pouvez ajouter cette fonction à votre profil par défaut, (Microsoft.PowerShell_profile.ps1), généralement situé à %USERPROFILE%\Documents\WindowsPowerShell.

8
répondu JeanT 2017-10-08 07:56:54

Toutes les réponses suggérant un changement permanent ont le même problème: elles cassent la valeur du registre path.

SetEnvironmentVariable tourne la REG_EXPAND_SZ valeur %SystemRoot%\system32 en REG_SZ valeur de C:\Windows\system32.

Toutes les autres variables du chemin sont également perdues. Ajouter de nouveaux en utilisant %myNewPath% ne fonctionnera plus.

Voici un script Set-PathVariable.ps1, que j'utilise pour résoudre ce problème:

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

J'explique le problème plus en détail dans un blog.

8
répondu Peter Hahndorf 2017-10-08 08:00:22

Comme Jonathan Leaders mentionné ici, il est important d'exécuter la commande / script elevated pour pouvoir changer les variables d'environnement pour 'machine' , mais l'exécution de certaines commandes elevated ne doit pas être faite avec les Extensions de la communauté, donc j'aimerais modifier et étendre Jeant's réponse d'une certaine manière, cette modification des variables de la machine peut également être effectuée même si le script lui-même n'est pas exécuté surélevé:

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
répondu Mehrdad Mirreza 2017-08-25 07:04:47

La plupart des réponses ne s'adressent pas à UAC. Cela couvre les questions UAC.

Installez D'abord les Extensions de la communauté PowerShell: choco install pscx via http://chocolatey.org/ (vous devrez peut-être redémarrer votre environnement shell).

Puis activez pscx

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

Ensuite, utilisez Invoke-Elevated

Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR
4
répondu Jonathan 2017-10-08 07:55:53

En S'appuyant sur la réponse de @ Michael Kropat, j'ai ajouté un paramètre pour ajouter le nouveau chemin à la variable PATHexistante et une vérification pour éviter l'ajout d'un chemin non existant:

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
répondu SBF 2018-02-05 14:24:02

MA SUGGESTION EST CELLE-CI j'ai testé cela pour ajouter C:\oracle\x64\bin Pour chemin en permanence et cela fonctionne bien.

$ENV:PATH

La première façon est simplement de faire:

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

Mais ce changement n'est pas permanent, $env:path reviendra par défaut à ce qu'il était avant dès que vous fermez votre terminal powershell et le rouvrez à nouveau. C'est parce que vous avez appliqué la modification au niveau de la session et non au niveau de la source (qui est le niveau du registre). Pour afficher la valeur globale de $env:chemin d'accès, faire:

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

, Ou, plus précisément:

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

Maintenant pour changer cela, nous avons d'abord capturer le chemin d'origine qui doit être modifié:

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

Maintenant, nous définissons à quoi devrait ressembler le nouveau chemin, dans ce cas, nous ajoutons un nouveau dossier:

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

Remarque: Assurez-vous que le $newpath ressemble à ce que vous voulez, sinon vous pourriez endommager votre système d'exploitation.

Maintenant, appliquez la nouvelle valeur:

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

Maintenant, faites une dernière vérification qu'il ressemble à ce que vous attendez il:

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

Vous pouvez maintenant redémarrer votre terminal powershell (ou même redémarrer la machine) et voir qu'il ne revient pas à son ancienne valeur. Notez que l'ordre des chemins peut changer de sorte qu'il soit dans l'ordre alphabétique, alors assurez-vous de vérifier toute la ligne, pour le rendre plus facile, vous pouvez diviser la sortie en lignes en utilisant le point-virgule comme un delimeter:

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