Festlegen von Windows PowerShell-Umgebungsvariablen

607

Ich habe herausgefunden, dass das Festlegen der Umgebungsvariablen PATH nur die alte Eingabeaufforderung betrifft. PowerShell scheint unterschiedliche Umgebungseinstellungen zu haben. Wie ändere ich die Umgebungsvariablen für PowerShell (v1)?

Hinweis:

Ich möchte meine Änderungen dauerhaft vornehmen, damit ich sie nicht jedes Mal festlegen muss, wenn ich PowerShell ausführe. Hat PowerShell eine Profildatei? So etwas wie Bash-Profil unter Unix?

Vasil
quelle
1
Ich möchte ein zentrales Profil auf einer Dateifreigabe haben. Synchronisation ist ein Schmerz. Erstellen eines Stub-Profils mit. \\ computer \ share \ path \ Profile.ps1 scheint ein Kludge zu sein (versuchen Sie es mit Notepad $ Profile). Es wäre schön, wenn es eine Möglichkeit gäbe, die automatische Variable $ Profile dauerhaft zu ändern.
Nathan Hartley
5
Nein, die PATH-Umgebung wirkt sich auch auf die Powershell-Eingabeaufforderung aus. Was sich jedoch unterscheidet, ist, dass Powershell keine in Anführungszeichen eingeschlossenen Pfade akzeptiert. Lösung: Entfernen Sie alle einschließenden Anführungszeichen ( ") in der
Pfadumgebungsvariablen
3
WENN SIE HIER FÜR PS> v1 LANDEN ... Weiter zu Nilzors Kommentar oben: Verwenden Sie diese Option, um alle "Pfade in der Umgebungsvariablen PATH für Ihre Sitzung zu entfernen:$($Env:PATH).Split(';') | %{ $str += "$($_.Trim('"'));" }; $Env:PATH=$str
d3r3kk

Antworten:

478

Das Ändern der tatsächlichen Umgebungsvariablen kann mithilfe der env: namespace / driveInformationen erfolgen. Dieser Code aktualisiert beispielsweise die Pfadumgebungsvariable:

$env:Path = "SomeRandomPath";             (replaces existing path) 
$env:Path += ";SomeRandomPath"            (appends to existing path)

Es gibt Möglichkeiten, Umgebungseinstellungen dauerhaft zu machen. Wenn Sie sie jedoch nur in PowerShell verwenden, ist es wahrscheinlich viel besser, Ihr Profil zum Initiieren der Einstellungen zu verwenden. Beim Start führt PowerShell alle .ps1- Dateien aus, die sich im WindowsPowerShellVerzeichnis unter " Eigene Dateien " befinden. In der Regel ist bereits eine Datei profile.ps1 vorhanden. Der Pfad auf meinem Computer ist

C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
JaredPar
quelle
38
$ profile ist eine automatische Variable, die für alle PowerShell-Hosts auf Ihr Benutzerprofil verweist.
JasonMArcher
16
Beachten Sie, dass (split-path $ profile) (um den enthaltenen Ordner abzurufen) mehrere Profildateien enthalten kann: profile.ps1 sollte von allen Hosts geladen werden, <Hostname> _profile.ps1 nur vom angegebenen Host. Für PowerShell.exe (Konsolenhost) ist dies Microsoft.PowerShell_profile.ps1.
Richard
10
Was ist, wenn meine Dokumente keinen Ordner WindowsPowerShell enthalten? Soll ich den Ordner und die Datei erstellen? Was soll ich in die Datei einfügen, wenn ich C:\path\to\file.extden Umgebungsvariablen hinzufügen möchte ? EDIT: habe es schon gefunden. Antwort ist ja, erstellen Sie es. Die Datei sollte aus 1 Zeile bestehen : $env:path += ;C:\path\to\file.ext".
Lewistrick
7
@ Lewisistrick Sie haben standardmäßig kein Profil. Ich habe diese Anweisungen befolgt, um eine zu erstellen: howtogeek.com/50236/customizing-your-powershell-profile
MikeB
16
Seien Sie vorsichtig dabei - es wird Ihren bestehenden Pfad blockieren. $env:Path = "SomeRandomPath"; Stattdessen - siehe @mloskot unten.
John Mark
626

Wenn Sie während einer PowerShell-Sitzung einige Zeit vorübergehend an die Umgebungsvariable PATH anhängen müssen, können Sie dies folgendermaßen tun:

$env:Path += ";C:\Program Files\GnuWin32\bin"
Mloskot
quelle
4
+1 :: Dieser Einzeiler ist sehr effektiv für sitzungsbasierte Aufrufe wie bei mingw ... IE $ env: PATH + = "; c: \ MinGW \ msys \ 1.0 \ bin" ^ {einige mingw bin ... }
Eddie B
2
und wie entferne ich einen Pfad?
Becko
11
Wenn Sie möchten, dass Ihr Pfad vor dem Standard aufgerufen wird, fügen Sie ihn am Anfang ein $env:Path = "C:\MyPath;$env:Path"
Michael Freidgeim
4
**** Vergessen Sie nicht das Semikolon am Anfang der anhängenden Zeichenfolge, wie in @ Kevin 's Kommentar zu sehen. Dies ist ziemlich offensichtlich, kann aber übersehen werden, wenn Sie den Code einfach kopieren / in die Antwort einfügen und am Ende des vorhandenen Pfads kein Semikolon haben. Ich werde versuchen, eine Bearbeitung einzureichen.
Matt Goodrich
1
@ MattGoodrich Ich habe Rollback zur vorherigen Revision
Cœur
278

Sie können Benutzer- / Systemumgebungsvariablen auch dauerhaft ändern (dh über Shell-Neustarts hinweg bleiben).

Ändern Sie eine Systemumgebungsvariable

[Environment]::SetEnvironmentVariable
     ("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)

Ändern Sie eine Benutzerumgebungsvariable

[Environment]::SetEnvironmentVariable
     ("INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User)

Verwendung aus Kommentaren - Zur Systemumgebungsvariablen hinzufügen

[Environment]::SetEnvironmentVariable(
    "Path",
    [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\bin",
    [EnvironmentVariableTarget]::Machine)

Eine stringbasierte Lösung ist auch möglich, wenn Sie keine Typen schreiben möchten

[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", "Machine")
hoge
quelle
6
Dies ist sehr nützlich für Systeme mit eingeschränktem Zugriff.
h0tw1r3
14
@AndresRiofrio, Ja, das ist permanent. Verwendung: [Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", [EnvironmentVariableTartget::Machine) Das Ergebnis dieser Änderung wird erst angezeigt, wenn Sie eine neue Powershell-Sitzung starten. Wenn Sie also $ env: Path unmittelbar nach dem Ausführen dieses Befehls überprüfen, sehen Sie, was $ env: Path vor dem Befehl war. Zum Aktualisieren schließen und öffnen Sie die Shell oder starten Sie eine neue Sitzung.
FLGMwt
7
@FLGMwt Sie haben einen Tippfehler, richtig ist: [Umgebung] :: SetEnvironmentVariable ("Pfad", $ env: Pfad + "; C: \ bin", [EnvironmentVariableTarget] :: Maschine)
Enthusiast
10
Sie können die Zeichenfolge "Maschine" oder "Benutzer" anstelle der gesamten .NET-Aufzählung schreiben. Von Technet .
Bouvierr
3
Ich denke, dass die Antwort auch die Verwendung zum Festlegen von Benutzervariablen wie dieser demonstrieren sollte[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";C:\bin", "User")
Saito
63

Über die PowerShell-Eingabeaufforderung:

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

Sie sollten dann den Text sehen:

SUCCESS: Specified value was saved.

Starten Sie Ihre Sitzung neu, und die Variable ist verfügbar. setxkann auch verwendet werden, um beliebige Variablen festzulegen. Geben Sie setx /?an der Eingabeaufforderung zur Dokumentation ein.

Stellen Sie sicher, dass Sie eine Kopie Ihres vorhandenen Pfads speichern, bevor Sie auf diese Weise mit Ihrem Pfad herumspielen, indem Sie dies $env:path >> a.outin einer PowerShell-Eingabeaufforderung tun .

tjb
quelle
5
Scheint nur zu funktionieren, wenn er als Administrator ausgeführt wird, und wird danach nur für PowerShell-Konsolen wirksam, die nicht regelmäßig ausgeführt werden.
Matanster
12
Autsch - wurde gerade von der 1024 Zeichenbegrenzung von setx getroffen; Zum Glück habe ich den Rat befolgt, um den vorhandenen Wert von $ end: Path aufzuzeichnen. Nur etwas zu beachten: superuser.com/questions/387619/…
Jonno
3
Warum nicht $env:PATHzuerst festlegen , setx /m PATH "$env:PATH"damit es lokal und global ohne Neustart der Shell angewendet wird?
Tresf
1
Nett! Obwohl setx kein natives Cmdlet ist, ist es dennoch eine viel bessere und leicht zu vergessende Alternative zu diesen abscheulichen, langwierigen .NET Framework-Aufrufen! Es ist verblüffend, dass selbst Powershell 7 noch kein offizielles Cmdlet enthält, um Envvars zu bestehen. Was. Fühlt sich an wie ein Feature, das Parität mit 'ls' haben sollte.
Jonas
27

Wie die Antwort von JeanT wollte ich eine Abstraktion, um den Pfad zu erweitern. Im Gegensatz zu JeanTs Antwort musste es ohne Benutzerinteraktion ausgeführt werden. Anderes Verhalten, nach dem ich gesucht habe:

  • Aktualisiert, $env:Pathdamit die Änderung in der aktuellen Sitzung wirksam wird
  • Behält die Änderung der Umgebungsvariablen für zukünftige Sitzungen bei
  • Fügt keinen doppelten Pfad hinzu, wenn derselbe Pfad bereits vorhanden ist

Falls es nützlich ist, hier ist es:

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

Schauen Sie sich meine Liste für die entsprechende Remove-EnvPathFunktion an.

Michael Kropat
quelle
16

Obwohl die aktuell akzeptierte Antwort in dem Sinne funktioniert, dass die Pfadvariable im Kontext von PowerShell dauerhaft aktualisiert wird, wird die in der Windows-Registrierung gespeicherte Umgebungsvariable nicht aktualisiert.

Um dies zu erreichen, können Sie natürlich auch PowerShell verwenden:

$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

Weitere Informationen finden Sie im Blogbeitrag. Verwenden Sie PowerShell, um Ihren Umgebungspfad zu ändern

Wenn Sie PowerShell-Community-Erweiterungen verwenden, lautet der richtige Befehl zum Hinzufügen eines Pfads zum Pfad der Umgebungsvariablen:

Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
gijswijs
quelle
12

Alle Antworten, die auf eine dauerhafte Änderung hinweisen, haben das gleiche Problem: Sie unterbrechen den Pfadregistrierungswert.

SetEnvironmentVariablewandelt den REG_EXPAND_SZWert %SystemRoot%\system32 in einen REG_SZWert von um C:\Windows\system32.

Alle anderen Variablen im Pfad gehen ebenfalls verloren. Das Hinzufügen neuer mit %myNewPath%wird nicht mehr funktionieren.

Hier ist ein Skript Set-PathVariable.ps1, mit dem ich dieses Problem behebe:

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

Ich erkläre das Problem ausführlicher in einem Blog-Beitrag .

Peter Hahndorf
quelle
Sollte dies sein: $ newPath = $ newPath -replace ";;", ";" ?
Joe Johnston
8

Dadurch wird der Pfad für die aktuelle Sitzung festgelegt und der Benutzer aufgefordert, ihn dauerhaft hinzuzufügen:

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

Sie können diese Funktion zu Ihrem Standardprofil ( Microsoft.PowerShell_profile.ps1) hinzufügen , das sich normalerweise unter befindet %USERPROFILE%\Documents\WindowsPowerShell.

JeanT
quelle
6

Aufbauend auf der Antwort von @Michael Kropat habe ich einen Parameter hinzugefügt, um den neuen Pfad der vorhandenen PATHVariablen voranzustellen , und eine Überprüfung, um das Hinzufügen eines nicht vorhandenen Pfads zu vermeiden:

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 ';'
            }
        }
    }
}
SBF
quelle
5

Wie Jonathan Leaders hier erwähnt hat , ist es wichtig, den Befehl / das Skript mit erhöhten Rechten auszuführen , um Umgebungsvariablen für 'machine' ändern zu können. Das Ausführen einiger Befehle mit erhöhten Rechten muss jedoch nicht mit den Community-Erweiterungen durchgeführt werden Um die Antwort von JeanT so zu ändern und zu erweitern , dass das Ändern von Maschinenvariablen auch dann durchgeführt werden kann, wenn das Skript selbst nicht erhöht ausgeführt wird:

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
    }

}
Mehrdad Mirreza
quelle
5

Die meisten Antworten richten sich nicht an die Benutzerkontensteuerung . Dies deckt UAC-Probleme ab.

Installieren Sie zuerst PowerShell Community Extensions: choco install pscxüber http://chocolatey.org/ (möglicherweise müssen Sie Ihre Shell-Umgebung neu starten).

Aktivieren Sie dann pscx

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

Dann benutze Invoke-Elevated

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

Mein Vorschlag ist dieser:

Ich habe dies getestet, um C:\oracle\x64\bines Pathdauerhaft zur Umgebungsvariablen hinzuzufügen , und dies funktioniert einwandfrei.

$ENV:PATH

Der erste Weg ist einfach zu tun:

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

Diese Änderung ist jedoch nicht dauerhaft. $env:pathSobald Sie Ihr PowerShell-Terminal schließen und erneut öffnen, wird standardmäßig auf den vorherigen Wert zurückgegriffen. Dies liegt daran, dass Sie die Änderung auf Sitzungsebene und nicht auf Quellenebene (der Registrierungsebene) angewendet haben. Gehen Sie wie folgt vor, um den globalen Wert von anzuzeigen $env:path:

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

Oder genauer:

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

Um dies zu ändern, erfassen wir zunächst den ursprünglichen Pfad, der geändert werden muss:

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

Nun definieren wir, wie der neue Pfad aussehen soll. In diesem Fall fügen wir einen neuen Ordner hinzu:

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

Hinweis: Stellen Sie sicher, dass die $newpath Aussehen so ist, wie Sie es möchten. Wenn nicht, können Sie Ihr Betriebssystem beschädigen.

Wenden Sie nun den neuen Wert an:

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

Führen Sie nun eine letzte Überprüfung durch, um festzustellen, wie es aussieht:

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

Sie können jetzt Ihr PowerShell-Terminal neu starten (oder sogar den Computer neu starten) und feststellen, dass es nicht wieder auf den alten Wert zurückgesetzt wird.

Beachten Sie, dass sich die Reihenfolge der Pfade möglicherweise in alphabetischer Reihenfolge ändert. Überprüfen Sie daher die gesamte Zeile. Zur Vereinfachung können Sie die Ausgabe in Zeilen aufteilen, indem Sie das Semikolon als Trennzeichen verwenden:

($env:path).split(“;”)
Ali Darabi
quelle
3

Öffnen Sie PowerShell und führen Sie Folgendes aus:

[Environment]::SetEnvironmentVariable("PATH", "$ENV:PATH;<path to exe>", "USER")
Job in
quelle
1

In PowerShell können Sie zum Umgebungsvariablenverzeichnis navigieren, indem Sie Folgendes eingeben:

Set-Location Env:

Dadurch gelangen Sie in das Verzeichnis Env:>. Aus diesem Verzeichnis heraus:

Geben Sie Folgendes ein, um alle Umgebungsvariablen anzuzeigen:

Env:\> Get-ChildItem

Geben Sie Folgendes ein, um eine bestimmte Umgebungsvariable anzuzeigen:

Env:\> $Env:<variable name>, e.g. $Env:Path

Geben Sie Folgendes ein, um eine Umgebungsvariable festzulegen:

Env:\> $Env:<variable name> = "<new-value>", e.g. $Env:Path="C:\Users\"

Geben Sie Folgendes ein, um eine Umgebungsvariable zu entfernen:

Env:\> remove-item Env:<variable name>, e.g. remove-item Env:SECRET_KEY

Weitere Informationen finden Sie unter Informationen zu Umgebungsvariablen .

Paul Maurer
quelle
0

Ich habe versucht, den Code von SBF und Michael ein wenig zu optimieren , um ihn kompakter zu machen.

Ich verlasse mich auf den Typzwang von PowerShell, bei dem Zeichenfolgen automatisch in Aufzählungswerte konvertiert werden, sodass ich das Suchwörterbuch nicht definiert habe.

Ich habe auch den Block herausgezogen, der den neuen Pfad basierend auf einer Bedingung zur Liste hinzufügt, sodass die Arbeit einmal ausgeführt und zur Wiederverwendung in einer Variablen gespeichert wird.

Es wird dann permanent oder nur auf die Sitzung angewendet, je nach $PathContainer Parameter .

Wir können den Codeblock in eine Funktion oder eine ps1-Datei einfügen, die wir direkt an der Eingabeaufforderung aufrufen. Ich habe mich für DevEnvAddPath.ps1 entschieden.

param(
    [Parameter(Position=0,Mandatory=$true)][String]$PathChange,

    [ValidateSet('Machine', 'User', 'Session')]
    [Parameter(Position=1,Mandatory=$false)][String]$PathContainer='Session',
    [Parameter(Position=2,Mandatory=$false)][Boolean]$PathPrepend=$false
)

[String]$ConstructedEnvPath = switch ($PathContainer) { "Session"{${env:Path};} default{[Environment]::GetEnvironmentVariable('Path', $containerType);} };
$PathPersisted = $ConstructedEnvPath -split ';';

if ($PathPersisted -notcontains $PathChange) {
    $PathPersisted = $(switch ($PathPrepend) { $true{,$PathChange + $PathPersisted;} default{$PathPersisted + $PathChange;} }) | Where-Object { $_ };

    $ConstructedEnvPath = $PathPersisted -join ";";
}

if ($PathContainer -ne 'Session') 
{
    # Save permanently to Machine, User
    [Environment]::SetEnvironmentVariable("Path", $ConstructedEnvPath, $PathContainer);
}

# Update the current session
${env:Path} = $ConstructedEnvPath;

Ich mache etwas Ähnliches für eine DevEnvRemovePath.ps1.

param(
    [Parameter(Position=0,Mandatory=$true)][String]$PathChange,

    [ValidateSet('Machine', 'User', 'Session')]
    [Parameter(Position=1,Mandatory=$false)][String]$PathContainer='Session'
)

[String]$ConstructedEnvPath = switch ($PathContainer) { "Session"{${env:Path};} default{[Environment]::GetEnvironmentVariable('Path', $containerType);} };
$PathPersisted = $ConstructedEnvPath -split ';';

if ($PathPersisted -contains $PathChange) {
    $PathPersisted = $PathPersisted | Where-Object { $_ -ne $PathChange };

    $ConstructedEnvPath = $PathPersisted -join ";";
}

if ($PathContainer -ne 'Session') 
{
    # Save permanently to Machine, User
    [Environment]::SetEnvironmentVariable("Path", $ConstructedEnvPath, $PathContainer);
}

# Update the current session
${env:Path} = $ConstructedEnvPath;

Bisher scheinen sie zu funktionieren.

Eniola
quelle
0

Nur die Antworten, die den Wert in die Registrierung übertragen, wirken sich auf eine dauerhafte Änderung aus (daher wirkt sich die Mehrheit der Antworten in diesem Thread, einschließlich der akzeptierten Antwort, nicht dauerhaft auf die ausPath ).

Die folgende Funktion funktioniert sowohl für Path/ PSModulePathals auch für User/ SystemTypen. Standardmäßig wird auch der neue Pfad zur aktuellen Sitzung hinzugefügt.

function AddTo-Path {
    param ( 
        [string]$PathToAdd,
        [Parameter(Mandatory=$true)][ValidateSet('System','User')][string]$UserType,
        [Parameter(Mandatory=$true)][ValidateSet('Path','PSModulePath')][string]$PathType
    )

    # AddTo-Path "C:\XXX" "PSModulePath" 'System' 
    if ($UserType -eq "System" ) { $RegPropertyLocation = 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' }
    if ($UserType -eq "User"   ) { $RegPropertyLocation = 'HKCU:\Environment' } # also note: Registry::HKEY_LOCAL_MACHINE\ format
    $PathOld = (Get-ItemProperty -Path $RegPropertyLocation -Name $PathType).$PathType
    "`n$UserType $PathType Before:`n$PathOld`n"
    $PathArray = $PathOld -Split ";" -replace "\\+$", ""
    if ($PathArray -notcontains $PathToAdd) {
        "$UserType $PathType Now:"   # ; sleep -Milliseconds 100   # Might need pause to prevent text being after Path output(!)
        $PathNew = "$PathOld;$PathToAdd"
        Set-ItemProperty -Path $RegPropertyLocation -Name $PathType -Value $PathNew
        Get-ItemProperty -Path $RegPropertyLocation -Name $PathType | select -ExpandProperty $PathType
        if ($PathType -eq "Path") { $env:Path += ";$PathToAdd" }                  # Add to Path also for this current session
        if ($PathType -eq "PSModulePath") { $env:PSModulePath += ";$PathToAdd" }  # Add to PSModulePath also for this current session
        "`n$PathToAdd has been added to the $UserType $PathType"
    }
    else {
        "'$PathToAdd' is already in the $UserType $PathType. Nothing to do."
    }
}

# Add "C:\XXX" to User Path (but only if not already present)
AddTo-Path "C:\XXX" "User" "Path"

# Just show the current status by putting an empty path
AddTo-Path "" "User" "Path"
YorSubs
quelle