การตั้งค่าตัวแปรสภาพแวดล้อม Windows PowerShell


605

ฉันพบว่าการตั้งค่าตัวแปรสภาพแวดล้อม PATH มีผลเฉพาะกับพรอมต์คำสั่งเก่าเท่านั้น PowerShell ดูเหมือนว่าจะมีการตั้งค่าสภาพแวดล้อมที่แตกต่างกัน ฉันจะเปลี่ยนตัวแปรสภาพแวดล้อมสำหรับ PowerShell (v1) ได้อย่างไร

บันทึก:

ฉันต้องการเปลี่ยนแปลงให้ถาวรดังนั้นฉันไม่ต้องตั้งค่าทุกครั้งที่เรียกใช้ PowerShell PowerShell มีไฟล์โปรไฟล์หรือไม่? สิ่งที่ชอบโปรไฟล์ทุบตีใน Unix?


1
ฉันต้องการมีโปรไฟล์กลางที่ตั้งอยู่บนการแชร์ไฟล์ การซิงโครไนซ์เป็นความเจ็บปวด การสร้างโปรไฟล์ต้นขั้วด้วย \\ computer \ share \ path \ Profile.ps1 ดูเหมือนว่า kludge (ลองใช้ Notepad $ Profile) มันจะดีถ้ามีวิธีในการเปลี่ยนตัวแปรอัตโนมัติ $ Profile อย่างถาวร
Nathan Hartley

5
ไม่มีสภาพแวดล้อมของเส้นทางไม่ส่งผลกระทบต่อคำสั่ง PowerShell พรอมต์เช่นกัน สิ่งที่แตกต่างคือพาวเวอร์เชลไม่ยอมรับเส้นทางที่อยู่ในเครื่องหมายคำพูด การแก้ไข: ลบอัญประกาศล้อมรอบทั้งหมด ( ") ในตัวแปรสภาพแวดล้อมของเส้นทาง
Nilzor

3
หากคุณอยู่ที่นี่เพื่อ PS> v1 ... นอกจากนี้ยังมีความคิดเห็นของ Nilzor ด้านบน: ใช้สิ่งนี้เพื่อลบทั้งหมด "จากเส้นทางในตัวแปรสภาพแวดล้อม PATH สำหรับเซสชันของคุณ:$($Env:PATH).Split(';') | %{ $str += "$($_.Trim('"'));" }; $Env:PATH=$str
d3r3kk

คำตอบ:


477

การเปลี่ยนตัวแปรสภาพแวดล้อมจริงสามารถทำได้โดยใช้env: namespace / driveข้อมูล ตัวอย่างเช่นรหัสนี้จะอัปเดตตัวแปรสภาพแวดล้อมของเส้นทาง:

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

มีวิธีที่จะทำให้การตั้งค่าสภาพแวดล้อมเป็นแบบถาวร แต่ถ้าคุณใช้เพียงแค่จาก PowerShell มันอาจจะดีกว่าถ้าคุณใช้โปรไฟล์ของคุณเพื่อเริ่มการตั้งค่า เมื่อเริ่มต้น PowerShell จะเรียกใช้ ไฟล์. ps1ใด ๆ ที่พบในWindowsPowerShellไดเรกทอรีภายใต้โฟลเดอร์ My Documents โดยทั่วไปคุณมี ไฟล์profile.ps1อยู่แล้ว เส้นทางบนคอมพิวเตอร์ของฉันคือ

C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1

38
$ profile เป็นตัวแปรอัตโนมัติที่ชี้ไปที่โปรไฟล์ผู้ใช้ของคุณสำหรับโฮสต์ PowerShell ทั้งหมด
JasonMArcher

16
โปรดทราบว่า (โปรไฟล์ $ path-path) (เพื่อให้ได้โฟลเดอร์ที่มี) สามารถมีหลายไฟล์โปรไฟล์: profile.ps1 ควรโหลดโดยโฮสต์ทั้งหมด <host-name> _profile.ps1 เพียงแค่โฮสต์ที่ระบุ สำหรับ PowerShell.exe (โฮสต์คอนโซล) นี่คือ Microsoft.PowerShell_profile.ps1
Richard

10
ถ้าฉันไม่มีโฟลเดอร์ WindowsPowerShell ในเอกสารของฉันล่ะ ฉันควรสร้างโฟลเดอร์และไฟล์หรือไม่ ฉันควรใส่อะไรลงในไฟล์ถ้าฉันต้องการเพิ่มC:\path\to\file.extให้กับตัวแปรสภาพแวดล้อม แก้ไข: พบแล้ว คำตอบคือใช่สร้างมันขึ้นมา ไฟล์ควรประกอบด้วยสาย $env:path += ;C:\path\to\file.ext"1:
Lewistrick

7
@Lewistrick คุณไม่มีโปรไฟล์ตามค่าเริ่มต้น ฉันทำตามคำแนะนำเหล่านี้เพื่อสร้าง: howtogeek.com/50236/customizing-your-powershell-profile
MikeB

16
ระวังการทำเช่นนี้ - มันจะบดบังเส้นทางที่มีอยู่ของคุณ $env:Path = "SomeRandomPath"; แทน - ดู @mloskot ด้านล่าง
John Mark

626

หากบางครั้งในระหว่างเซสชัน PowerShell คุณต้องผนวกเข้ากับตัวแปรสภาพแวดล้อม PATH ชั่วคราวคุณสามารถทำได้ด้วยวิธีนี้:

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

4
+1 :: ซับหนึ่งนี้ค่อนข้างมีประสิทธิภาพสำหรับการร้องขอเซสชันตามด้วย mingw ... IE $ env: PATH + = "; c: \ MinGW \ msys \ 1.0 \ bin" ^ {bin บาง mingw ... }
Eddie B

2
และฉันจะลบเส้นทางได้อย่างไร
becko

11
หากคุณต้องการเส้นทางของคุณที่จะเรียกก่อนหนึ่งมาตรฐานใส่มันที่จุดเริ่มต้น $env:Path = "C:\MyPath;$env:Path"
Michael Freidgeim

4
**** อย่าลืมเครื่องหมายอัฒภาคตอนเริ่มต้นของสตริงต่อท้ายดังที่เห็นในความคิดเห็นของ @Kevin สิ่งนี้ค่อนข้างชัดเจน แต่อาจพลาดได้หากคุณคัดลอก / วางรหัสในคำตอบและไม่มีเซมิโคลอนที่ท้ายเส้นทางที่มีอยู่ ฉันจะพยายามส่งการแก้ไข
Matt Goodrich

1
@MattGoodrich ผมเคยย้อนกลับไปแก้ไขก่อนหน้า
Cœur

278

คุณยังสามารถแก้ไขตัวแปรสภาพแวดล้อมของผู้ใช้ / ระบบอย่างถาวร (เช่นจะคงอยู่ตลอดการรีสตาร์ทเชลล์) ด้วยสิ่งต่อไปนี้:

ปรับเปลี่ยนตัวแปรสภาพแวดล้อมระบบ

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

ปรับเปลี่ยนตัวแปรสภาพแวดล้อมของผู้ใช้

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

การใช้งานจากความคิดเห็น - เพิ่มไปยังตัวแปรสภาพแวดล้อมของระบบ

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

วิธีการแก้ปัญหาแบบ String สามารถทำได้หากคุณไม่ต้องการเขียนชนิด

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

6
สิ่งนี้มีประโยชน์มากสำหรับระบบการเข้าถึงที่ จำกัด
h0tw1r3

14
@AndresRiofrio ใช่นี่เป็นสิ่งที่ถาวร การใช้งาน: [Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", [EnvironmentVariableTartget::Machine) คุณจะไม่เห็นผลลัพธ์ของการเปลี่ยนแปลงนี้จนกว่าคุณจะเริ่มเซสชัน PowerShell ใหม่ นั่นคือถ้าคุณตรวจสอบ $ env: พา ธ ทันทีหลังจากรันคำสั่งนี้คุณจะเห็นว่า $ env: พา ธ อยู่ก่อนคำสั่ง หากต้องการอัปเดตให้ปิดและเปิดเชลล์หรือเริ่มเซสชันใหม่
FLGMwt

7
@FLGMwt คุณพิมพ์ผิดถูกต้องคือ: [สิ่งแวดล้อม] :: SetEnvironmentVariable ("Path", $ env: Path + "; C: \ bin", [EnvironmentVariableTarget] :: เครื่องจักร)
กระตือรือร้น 1

10
คุณสามารถเขียนสตริง "Machine" หรือ "User" แทนที่จะเป็น. NET enum ทั้งหมด จากเปอเรเตอร์
bouvierr

3
ฉันคิดว่าคำตอบนั้นควรแสดงให้เห็นถึงการใช้งานสำหรับการตั้งค่าตัวแปรผู้ใช้เช่นนี้[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";C:\bin", "User")
Saito

63

จากพรอมต์ PowerShell:

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

จากนั้นคุณควรเห็นข้อความ:

SUCCESS: Specified value was saved.

รีสตาร์ทเซสชันของคุณและตัวแปรจะพร้อมใช้งาน setxยังสามารถใช้ในการตั้งค่าตัวแปรโดยพลการ พิมพ์setx /?ที่พรอมต์เพื่อรับเอกสาร

ก่อนที่จะล้อเล่นกับเส้นทางของคุณด้วยวิธีนี้ตรวจสอบให้แน่ใจว่าคุณบันทึกสำเนาของเส้นทางที่มีอยู่ของคุณโดยทำ$env:path >> a.outในพรอมต์ PowerShell


5
ดูเหมือนว่าจะทำงานเมื่อ 'เรียกใช้ในฐานะผู้ดูแลระบบ' เท่านั้นและหลังจากนั้นจะมีผลเฉพาะกับ 'ใช้งานในฐานะผู้ดูแลระบบ' PowerShell คอนโซลไม่ทำงานเป็นประจำ
matanster


12
Ouch - เพิ่งได้รับการจำกัดความยาว 1024 อักขระของ setx; โชคดีที่ฉันทำตามคำแนะนำเพื่อบันทึกค่าที่มีอยู่ของ $ end: Path สิ่งที่ต้องระวัง: superuser.com/questions/387619/…
Jonno

3
ทำไมไม่ตั้งค่า$env:PATHก่อนจากนั้นsetx /m PATH "$env:PATH"จึงใช้กับโลคัลและส่วนกลางโดยไม่ต้องเชลล์รีสตาร์ท
tresf

1
ดี! แม้ว่า setx ไม่ได้เป็น cmdlet ดั้งเดิม แต่ก็ยังเป็นทางเลือกที่ดีกว่าและลืมได้ง่ายกว่าผู้ที่เรียกใช้. NET Framework NET ที่น่ารังเกียจ มันทำให้งงงันที่แม้แต่ Powershell 7 ก็ยังไม่ได้มาพร้อมกับ cmdlet อย่างเป็นทางการที่จะคงสภาพ envars อะไร. รู้สึกเหมือนฟีเจอร์ที่ควรมีพาริตี้กับ 'ls'
Jonas

27

เช่นเดียวกับคำตอบของ JeanTฉันต้องการสิ่งที่เป็นนามธรรมเกี่ยวกับการเพิ่มเส้นทาง ต่างจากคำตอบของ JeanT ฉันต้องการให้มันทำงานโดยไม่ต้องมีการโต้ตอบกับผู้ใช้ พฤติกรรมอื่น ๆ ที่ฉันกำลังมองหา:

  • อัปเดต$env:Pathเพื่อให้การเปลี่ยนแปลงมีผลในเซสชันปัจจุบัน
  • ยังคงมีการเปลี่ยนแปลงตัวแปรสภาพแวดล้อมสำหรับเซสชันในอนาคต
  • ไม่เพิ่มเส้นทางที่ซ้ำกันเมื่อมีเส้นทางเดียวกันอยู่แล้ว

ในกรณีที่มีประโยชน์นี่คือ:

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

ตรวจสอบส่วนสำคัญของฉันสำหรับRemove-EnvPathฟังก์ชั่นที่เกี่ยวข้อง


16

แม้ว่าคำตอบที่ยอมรับในปัจจุบันจะทำงานในแง่ที่ว่าตัวแปรเส้นทางได้รับการปรับปรุงอย่างถาวรจากบริบทของ PowerShell แต่ก็ไม่ได้ปรับปรุงตัวแปรสภาพแวดล้อมที่เก็บไว้ในรีจิสทรีของ Windows

เพื่อให้บรรลุนั้นคุณสามารถใช้ 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

ข้อมูลเพิ่มเติมอยู่ในบล็อกโพสต์ใช้ PowerShell เพื่อปรับเปลี่ยนเส้นทางสิ่งแวดล้อมของคุณ

หากคุณใช้ส่วนขยายชุมชน PowerShell คำสั่งที่เหมาะสมเพื่อเพิ่มพา ธ ไปยังพา ธ ตัวแปรสภาพแวดล้อมคือ:

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

12

คำตอบทั้งหมดที่แนะนำการเปลี่ยนแปลงอย่างถาวรมีปัญหาเดียวกัน: พวกเขาแบ่งค่ารีจิสทรีของเส้นทาง

SetEnvironmentVariableเปลี่ยนREG_EXPAND_SZค่า%SystemRoot%\system32 เป็นค่าของREG_SZC:\Windows\system32

ตัวแปรอื่น ๆ ในเส้นทางจะหายไปเช่นกัน การเพิ่มรายการใหม่ที่ใช้%myNewPath%จะไม่ทำงานอีกต่อไป

นี่คือสคริปต์Set-PathVariable.ps1ที่ฉันใช้เพื่อแก้ไขปัญหานี้:

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

ผมอธิบายปัญหาในรายละเอียดในบล็อกโพสต์


ควรเป็นเช่นนี้: $ newPath = $ newPath -replace ";;", ";" ?
โจจอห์นสตัน

8

ชุดนี้จะกำหนดเส้นทางสำหรับเซสชันปัจจุบันและแจ้งให้ผู้ใช้เพิ่มอย่างถาวร:

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

คุณสามารถเพิ่มฟังก์ชั่นนี้ในโปรไฟล์เริ่มต้นของคุณ ( Microsoft.PowerShell_profile.ps1) %USERPROFILE%\Documents\WindowsPowerShellมักจะตั้งอยู่ที่


6

การสร้างคำตอบของ @Michael Kropatฉันได้เพิ่มพารามิเตอร์เพื่อเพิ่มเส้นทางใหม่ให้กับPATHตัวแปรที่มีอยู่และการตรวจสอบเพื่อหลีกเลี่ยงการเพิ่มเส้นทางที่ไม่มีอยู่:

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

5

ขณะที่โจนาธานผู้นำกล่าวถึงที่นี่มันเป็นสิ่งสำคัญที่จะเรียกใช้คำสั่ง / script สูงเพื่อให้สามารถตัวแปรสภาพแวดล้อมที่เปลี่ยนแปลง'เครื่อง'แต่ใช้คำสั่งบางอย่างสูงไม่ได้มีการดำเนินการกับส่วนขยายของชุมชนดังนั้นฉันต้องการ เพื่อแก้ไขและขยายคำตอบของ JeanT ในลักษณะที่เปลี่ยนแปลงตัวแปรของเครื่องสามารถทำได้แม้ว่าสคริปต์จะไม่ได้รับการยกระดับ:

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

คำตอบส่วนใหญ่จะไม่อยู่UAC สิ่งนี้ครอบคลุมถึงปัญหาของ UAC

ก่อนติดตั้ง PowerShell Community Extensions: choco install pscxผ่านhttp://chocolatey.org/ (คุณอาจต้องรีสตาร์ทระบบเชลล์)

จากนั้นเปิดใช้งาน pscx

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

จากนั้นใช้ Invoke-Elevated

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

4

คำแนะนำของฉันคืออันนี้:

ฉันได้ทดสอบสิ่งนี้เพื่อเพิ่มC:\oracle\x64\binตัวแปรสภาพแวดล้อมPathอย่างถาวรและทำงานได้ดี

$ENV:PATH

วิธีแรกคือทำ:

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

แต่การเปลี่ยนแปลงนี้ไม่ถาวร $env:pathจะกลับไปเป็นค่าเริ่มต้นก่อนหน้านี้ทันทีที่คุณปิดเทอร์มินัล PowerShell และเปิดใหม่อีกครั้ง นั่นเป็นเพราะคุณได้ใช้การเปลี่ยนแปลงในระดับเซสชันและไม่ได้อยู่ในระดับต้นทาง (ซึ่งคือระดับรีจิสทรี) หากต้องการดูค่าทั่วโลกของ$env:pathให้ทำ:

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

หรือเฉพาะเจาะจงมากขึ้น:

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

ตอนนี้เพื่อเปลี่ยนแปลงสิ่งนี้ก่อนอื่นเราจะจับภาพพา ธ ดั้งเดิมที่ต้องแก้ไข:

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

ตอนนี้เรากำหนดเส้นทางใหม่ที่ควรมีลักษณะอย่างไร ในกรณีนี้เรากำลังผนวกโฟลเดอร์ใหม่:

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

หมายเหตุ: ตรวจสอบให้แน่ใจว่า$newpathรูปลักษณ์ที่คุณต้องการให้เป็นอย่างไร ถ้าไม่เช่นนั้นคุณอาจสร้างความเสียหายให้กับระบบปฏิบัติการของคุณ

ตอนนี้ใช้ค่าใหม่:

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

ตอนนี้ให้ตรวจสอบขั้นสุดท้ายหนึ่งครั้งเพื่อให้ดูเหมือนว่าคุณจะคาดหวังว่า:

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

ตอนนี้คุณสามารถรีสตาร์ท Terminal PowerShell ของคุณ (หรือแม้กระทั่งรีบูตเครื่อง) และดูว่ามันไม่ย้อนกลับไปเป็นค่าเดิมอีกครั้ง

โปรดสังเกตว่าการเรียงลำดับเส้นทางอาจเปลี่ยนไปตามลำดับตัวอักษรดังนั้นโปรดตรวจสอบทั้งบรรทัด เพื่อให้ง่ายขึ้นคุณสามารถแบ่งเอาต์พุตออกเป็นแถวโดยใช้เซมิโคลอนเป็นตัวคั่น:

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

3

เปิด PowerShell แล้วเรียกใช้:

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

1

ภายใน PowerShell หนึ่งสามารถนำทางไปยังไดเรกทอรีตัวแปรสภาพแวดล้อมโดยการพิมพ์:

Set-Location Env:

สิ่งนี้จะนำคุณไปยังไดเรกทอรี Env:> จากภายในไดเรกทอรีนี้:

หากต้องการดูตัวแปรสภาพแวดล้อมทั้งหมดให้พิมพ์:

Env:\> Get-ChildItem

หากต้องการดูตัวแปรสภาพแวดล้อมเฉพาะให้พิมพ์:

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

ในการตั้งค่าตัวแปรสภาพแวดล้อมให้พิมพ์:

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

หากต้องการลบตัวแปรสภาพแวดล้อมให้พิมพ์:

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

ข้อมูลเพิ่มเติมในเกี่ยวกับตัวแปรของสภาพแวดล้อม


0

ฉันพยายามเพิ่มประสิทธิภาพของ SBFและโค้ดของ Michaelเล็กน้อยเพื่อให้กะทัดรัดยิ่งขึ้น

ฉันใช้การบังคับประเภทของ PowerShell ซึ่งจะแปลงสตริงเป็นค่า enum โดยอัตโนมัติดังนั้นฉันจึงไม่ได้กำหนดพจนานุกรมการค้นหา

ฉันดึงบล็อกที่เพิ่มเส้นทางใหม่ไปยังรายการตามเงื่อนไขเพื่อให้งานเสร็จสิ้นครั้งเดียวและเก็บไว้ในตัวแปรเพื่อนำกลับมาใช้ใหม่

มันจะถูกนำไปใช้อย่างถาวรหรือเพียงแค่ไปที่เซสชั่นขึ้นอยู่กับ$PathContainerพารามิเตอร์

เราสามารถใส่บล็อกของรหัสในฟังก์ชั่นหรือไฟล์ ps1 ที่เราเรียกโดยตรงจากพรอมต์คำสั่ง ฉันไปกับ DevEnvAddPath.ps1

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;

ฉันทำสิ่งที่คล้ายกันสำหรับ 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;

จนถึงตอนนี้พวกเขาดูเหมือนจะทำงาน


0

เฉพาะคำตอบที่ผลักค่าลงในรีจิสทรีเท่านั้นที่มีผลต่อการเปลี่ยนแปลงอย่างถาวร (ดังนั้นคำตอบส่วนใหญ่ในเธรดนี้รวมถึงคำตอบที่ยอมรับจะไม่ส่งผลกระทบอย่างถาวรต่อPath)

ฟังก์ชั่นต่อไปนี้ใช้ได้ทั้งPath/ PSModulePathและสำหรับUser/ Systemประเภท มันจะเพิ่มเส้นทางใหม่ให้กับเซสชันปัจจุบันโดยค่าเริ่มต้น

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"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.