Ustawianie zmiennej ścieżki Windows PowerShell

Dowiedziałem się, że ustawienie zmiennej środowiskowej PATH wpływa tylko na stary wiersz polecenia. PowerShell wydaje się mieć różne ustawienia środowiska. Jak zmienić zmienne środowiskowe dla PowerShell (v1)?

Uwaga:

Chcę, aby moje zmiany były stałe, więc nie muszę ich ustawiać za każdym razem, gdy uruchamiam PowerShell. Czy PowerShell ma plik profilu? Coś jak Profil Basha na Unixie?

Author: Peter Mortensen, 2009-04-03

12 answers

Zmiana rzeczywistych zmiennych środowiskowych może być dokonana przez korzystanie z informacji env: namespace / drive. Przykładowo, to kod zaktualizuje zmienną środowiskową path:

$env:Path = "SomeRandomPath";

Są sposoby, aby ustawienia środowiska stały, ale jeśli używasz ich tylko z PowerShell, prawdopodobnie o wiele lepiej użyć swojego profilu, aby zainicjować ustawienia. Po uruchomieniu PowerShell uruchomi dowolny . ps1 pliki, które znajduje w katalogu WindowsPowerShell pod Moje dokumenty. Zazwyczaj ty mieć profil. ps1 / align = "left" / Ścieżka na moim komputerze to

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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-08 07:53:38

Jeśli jakiś czas podczas sesji PowerShell, musisz tymczasowo zmodyfikować zmienną środowiskową PATH, można zrób to tak:

$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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-18 10:57:14

Możesz również trwale modyfikować zmienne środowiskowe użytkownika / systemu (tzn. będą trwałe w przypadku restartów powłoki) za pomocą następującego

### 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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-16 14:25:54

Z wiersza polecenia PowerShell:

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

Powinieneś zobaczyć tekst:

SUCCESS: Specified value was saved.

Uruchom ponownie sesję, a zmienna będzie dostępna. setx może być również używany do ustawiania dowolnych zmiennych. Wpisz setx /? w wierszu polecenia dokumentacji.

Zanim zmienisz ścieżkę w ten sposób, upewnij się, że zapisujesz kopię istniejącej ścieżki, wykonując $env:path >> a.out w monicie 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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-10 13:07:41

Chociaż obecna akceptowana odpowiedź działa w tym sensie, że zmienna path zostaje trwale zaktualizowana z kontekstu PowerShell, to w rzeczywistości nie aktualizuje zmiennej środowiskowej przechowywanej w rejestrze systemu windows. Aby to osiągnąć, możesz oczywiście również użyć 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

Więcej informacji tutaj: http://blogs.technet.com/b/heyscriptingguy/archive/2011/07/23/use-powershell-to-modify-your-environmental-path.aspx

Jeśli używasz społeczności PowerShell rozszerzenia, właściwym poleceniem dodawania ścieżki do zmiennej środowiskowej path jest:
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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-17 20:06:35

Podobnie jak odpowiedź Jeanta , chciałem abstrakcji wokół dodawania do ścieżki. W przeciwieństwie do odpowiedzi Jeanta, potrzebowałem go, aby działał bez interakcji z użytkownikiem. Inne zachowanie, którego szukałem:

  • aktualizacje $env:Path więc zmiana wchodzi w życie w bieżącej sesji
  • Persists the environment variable change for future sessions
  • nie dodaje zduplikowanej ścieżki, gdy ta sama ścieżka już istnieje

W przypadku, gdy jest to przydatne, tutaj jest:

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

Zobacz też mój gist dla odpowiedniej Remove-EnvPath funkcji.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:27

Ustawia ścieżkę bieżącej sesji i prosi użytkownika o dodanie jej na stałe:

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

Możesz dodać tę funkcję do domyślnego profilu (Microsoft.PowerShell_profile.ps1), Zwykle znajdującego się pod adresem %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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-08 07:56:54

Wszystkie odpowiedzi sugerujące stałą zmianę mają ten sam problem: łamią wartość rejestru path.

SetEnvironmentVariable zamienia REG_EXPAND_SZ wartość %SystemRoot%\system32 na REG_SZ wartość C:\Windows\system32.

Wszelkie inne zmienne w ścieżce również zostają utracone. Dodawanie nowych za pomocą %myNewPath% nie będzie już działać.

Oto skrypt Set-PathVariable.ps1, którego używam do rozwiązania tego problemu:

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

Wyjaśniam problem bardziej szczegółowo w poście na blogu.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-08 08:00:22

Jak wspomniał Jonathan Leaders tutaj , ważne jest, aby uruchomić polecenie / skrypt elevated, aby móc zmieniać zmienne środowiskowe dla 'machine' , ale uruchamianie niektórych poleceń elevated nie musi być wykonywane z rozszerzeniami społeczności, więc chciałbym zmodyfikować i rozszerzyć jeanta. odpowiedź w taki sposób, że zmiana zmiennych maszyny również może być wykonana, nawet jeśli sam skrypt nie jest uruchomiony:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-25 07:04:47

Większość odpowiedzi Nie dotyczy UAC . Dotyczy to kwestii UAC.

Najpierw zainstaluj rozszerzenia społeczności PowerShell: choco install pscx poprzez http://chocolatey.org/ (być może trzeba będzie ponownie uruchomić środowisko powłoki).

Następnie włącz pscx

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

Następnie użyj 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-08 07:55:53

Bazując na odpowiedzi @Michael Kropat dodałem parametr poprzedzający nową ścieżkę do istniejącej zmiennej PATH oraz sprawdzanie, aby uniknąć dodania nieistniejącej ścieżki:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-05 14:24:02

MOJA SUGESTIA JEST TAKA przetestowałem to, aby dodać C:\oracle\x64\bin do ścieżki na stałe i to działa dobrze.

$ENV:PATH

Pierwszy sposób jest po prostu zrobić:

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

Ale ta zmiana nie jest permenantly, $env: path będzie domyślnie z powrotem do tego, co było wcześniej, jak tylko zamkniesz Terminal powershell i ponownie go otworzysz. Dzieje się tak dlatego, że zmiana została zastosowana na poziomie sesji, a nie na poziomie źródłowym (czyli na poziomie rejestru). Aby zobaczyć globalną wartość $env: path, do:

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

A dokładniej:

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

Teraz, aby to zmienić, najpierw przechwycimy oryginalną ścieżkę, która musi zostać zmodyfikowana:

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

Teraz definiujemy, jak powinna wyglądać nowa ścieżka, w tym przypadku dodajemy nowy folder:

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

Uwaga: Upewnij się, że $newpath wygląda tak, jak chcesz, aby wyglądać, jeśli nie, to możesz uszkodzić swój system operacyjny.

Zastosuj teraz nową wartość:

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

Teraz zrób jeszcze jedną ostatnią kontrolę, że wygląda tak, jak oczekujesz it:

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

Możesz teraz zrestartować terminal powershell (lub nawet zrestartować maszynę) i zobaczyć, że nie powróci on ponownie do swojej starej wartości. Uwaga kolejność ścieżek może się zmienić tak, że jest w porządku alfabetycznym, więc upewnij się, że sprawdzisz całą linię, aby ułatwić, możesz podzielić wyjście na wiersze za pomocą średnika jako delimetra:

($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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-20 09:57:46