Đặt các biến môi trường Windows PowerShell


608

Tôi đã phát hiện ra rằng việc thiết lập biến môi trường PATH chỉ ảnh hưởng đến dấu nhắc lệnh cũ. PowerShell dường như có các cài đặt môi trường khác nhau. Làm cách nào để thay đổi các biến môi trường cho PowerShell (v1)?

Ghi chú:

Tôi muốn thực hiện các thay đổi của mình vĩnh viễn, vì vậy tôi không phải thiết lập nó mỗi khi tôi chạy PowerShell. PowerShell có tệp hồ sơ không? Một cái gì đó giống như hồ sơ Bash trên Unix?


1
Tôi muốn có một hồ sơ trung tâm nằm trên một chia sẻ tập tin. Đồng bộ hóa là một nỗi đau. Tạo một hồ sơ sơ khai với. \ máy tính \ share \ path \ Profile.ps1 có vẻ giống như một loại bùn (thử Notepad $ Profile). Sẽ thật tuyệt nếu có một cách để thay đổi vĩnh viễn biến tự động $ Profile.
Nathan Hartley

5
Không có môi trường PATH nào cũng ảnh hưởng đến dấu nhắc lệnh powershell. Điều khác biệt mặc dù là powershell không chấp nhận các đường dẫn kèm theo dấu ngoặc kép. Giải pháp: xóa tất cả các dấu ngoặc kép ( ") trong biến môi trường đường dẫn
Nilzor

3
NẾU BẠN ĐẤT Ở ĐÂY CHO PS> v1 ... Thêm vào nhận xét của Nilzor ở trên: Sử dụng cách này để xóa tất cả "khỏi các đường dẫn trong biến môi trường PATH cho phiên của bạn:$($Env:PATH).Split(';') | %{ $str += "$($_.Trim('"'));" }; $Env:PATH=$str
d3r3kk

Câu trả lời:


479

Thay đổi các biến môi trường thực tế có thể được thực hiện bằng cách sử dụng env: namespace / drivethông tin. Ví dụ, mã này sẽ cập nhật biến môi trường đường dẫn:

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

Có nhiều cách để tạo cài đặt môi trường vĩnh viễn, nhưng nếu bạn chỉ sử dụng chúng từ PowerShell, có lẽ tốt hơn là sử dụng hồ sơ của bạn để bắt đầu cài đặt. Khi khởi động, PowerShell sẽ chạy mọi tệp .ps1 mà nó tìm thấy trong WindowsPowerShellthư mục trong thư mục Tài liệu của tôi. Thông thường, bạn đã có một tập tin profile.ps1 ở đó. Đường dẫn trên máy tính của tôi là

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

38
$ profile là một biến tự động trỏ đến hồ sơ người dùng của bạn cho tất cả các máy chủ PowerShell.
JasonMArcher

16
Lưu ý rằng (split-path $ profile) (để lấy thư mục chứa) có thể chứa nhiều tệp hồ sơ: profile.ps1 phải được tải bởi tất cả các máy chủ, <tên máy chủ> _profile.ps1 chỉ bởi máy chủ được chỉ định. Đối với PowerShell.exe (máy chủ bảng điều khiển), đây là Microsoft.PowerShell_profile.ps1.
Richard

10
Nếu tôi không có thư mục WindowsPowerShell trong tài liệu của mình thì sao? Tôi có nên tạo thư mục và tập tin? Tôi nên đặt gì trong tệp nếu tôi muốn thêm C:\path\to\file.extvào các biến môi trường? EDIT: đã tìm thấy nó rồi. Trả lời là có, tạo ra nó. Các tập tin nên bao gồm 1 dòng : $env:path += ;C:\path\to\file.ext".
Lewistrick 11/03/2015

7
@Lewistrick Bạn không có hồ sơ theo mặc định. Tôi đã làm theo các hướng dẫn này để tạo một: howtogeek.com/50236/customizing-your-powershell-profile
MikeB

16
Hãy cẩn thận làm điều này - nó sẽ chặn đường đi hiện tại của bạn. $env:Path = "SomeRandomPath"; Thay vào đó - xem @mloskot, bên dưới.
John Mark

626

Nếu, đôi khi trong phiên PowerShell, bạn cần tạm thời thêm vào biến môi trường PATH, bạn có thể thực hiện theo cách này:

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

4
+1 :: Lớp lót này khá hiệu quả đối với các yêu cầu dựa trên phiên như với mingw ... IE $ env: PATH + = "; c: \ MinGW \ msys \ 1.0 \ bin" ^ {một số mingw bin ... }
Eddie B

2
và làm cách nào để xóa một đường dẫn?
vẫy gọi

11
Nếu bạn cần đường dẫn của mình được gọi trước tiêu chuẩn, hãy chèn nó vào đầu $env:Path = "C:\MyPath;$env:Path"
Michael Freidgeim

4
**** Đừng quên dấu chấm phẩy khi bắt đầu chuỗi nối thêm, như đã thấy trong nhận xét của @Kevin. Điều này khá rõ ràng, nhưng có thể bị bỏ qua nếu bạn chỉ cần sao chép / dán mã trong câu trả lời và không có dấu chấm phẩy ở cuối đường dẫn hiện có. Tôi sẽ cố gắng gửi một bản chỉnh sửa.
Matt Goodrich

1
@Mattoodrich Tôi đã quay trở lại phiên bản trước
Cœur

278

Bạn cũng có thể sửa đổi vĩnh viễn các biến môi trường của người dùng / hệ thống (nghĩa là sẽ liên tục khởi động lại shell) bằng cách sau:

Sửa đổi một biến môi trường hệ thống

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

Sửa đổi biến môi trường người dùng

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

Sử dụng từ ý kiến ​​- thêm vào biến môi trường hệ thống

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

Giải pháp dựa trên chuỗi cũng có thể nếu bạn không muốn viết các loại

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

6
Điều này rất hữu ích cho các hệ thống truy cập hạn chế.
h0tw1r3

14
@AndresRiofrio, Vâng, điều này là vĩnh viễn. Cách sử dụng: [Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", [EnvironmentVariableTartget::Machine) Bạn sẽ không thấy kết quả của sự thay đổi này cho đến khi bạn bắt đầu một phiên quyền hạn mới. Đó là, nếu bạn kiểm tra $ env: Đường dẫn ngay sau khi chạy lệnh này, bạn sẽ thấy $ env: Đường dẫn là gì trước lệnh. Để cập nhật, đóng và mở shell hoặc bắt đầu một phiên mới.
FLGMwt

7
@FLGMwt bạn có một lỗi đánh máy, đúng là: [Môi trường] :: SetEnvironmentVariable ( "Path", $ env: Đường dẫn + "; C: \ bin", [EnvironmentVariableTarget] :: Machine)
enthus1ast

10
Bạn có thể viết chuỗi "Máy" hoặc "Người dùng" thay vì toàn bộ .NET enum. Từ Technet .
bouvierr

3
Tôi nghĩ rằng câu trả lời đó cũng sẽ chứng minh việc sử dụng để đặt biến người dùng, như thế này[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";C:\bin", "User")
Saito

63

Từ lời nhắc PowerShell:

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

Sau đó bạn sẽ thấy văn bản:

SUCCESS: Specified value was saved.

Khởi động lại phiên của bạn và biến sẽ có sẵn. setxcũng có thể được sử dụng để đặt các biến tùy ý. Nhập setx /?tại dấu nhắc cho tài liệu.

Trước khi làm rối đường dẫn của bạn theo cách này, hãy đảm bảo rằng bạn lưu một bản sao của đường dẫn hiện tại bằng cách thực hiện $env:path >> a.outtrong lời nhắc PowerShell.


5
Có vẻ như chỉ hoạt động khi 'chạy với tư cách quản trị viên' và sau đó chỉ có hiệu lực đối với 'chạy dưới dạng bảng điều khiển PowerShell của quản trị viên, không chạy thường xuyên.
matanster


12
Ouch - vừa bị giới hạn 1024 ký tự của setx; rất may tôi đã làm theo lời khuyên để ghi lại giá trị hiện tại của $ end: Path. Chỉ cần một cái gì đó để nhận biết: superuser.com/questions/387619/
Kiếm

3
Tại sao không đặt $env:PATHđầu tiên, sau đó setx /m PATH "$env:PATH"để nó áp dụng cục bộ và toàn cầu mà không cần khởi động lại shell?
tresf

1
Đẹp! Mặc dù setx không phải là một lệnh ghép ngắn gốc, nhưng vẫn là một lựa chọn tốt hơn và dễ bị lãng quên hơn nhiều so với các cuộc gọi .NET Framework dài ngoằng đáng ghét! Thật khó hiểu khi ngay cả Powershell 7 vẫn không đi kèm với một lệnh ghép ngắn chính thức để tiếp tục các envvars. Gì. Cảm thấy giống như một tính năng nên tương đương với 'ls'.
Jonas

27

Giống như câu trả lời của JeanT , tôi muốn một sự trừu tượng xung quanh việc thêm vào đường dẫn. Không giống như câu trả lời của JeanT, tôi cần nó để chạy mà không cần sự tương tác của người dùng. Hành vi khác tôi đang tìm kiếm:

  • Cập nhật $env:Pathđể thay đổi có hiệu lực trong phiên hiện tại
  • Duy trì thay đổi biến môi trường cho các phiên trong tương lai
  • Không thêm một đường dẫn trùng lặp khi cùng một đường dẫn đã tồn tại

Trong trường hợp nó hữu ích, đây là:

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

Kiểm tra ý chính của tôi cho các Remove-EnvPathchức năng tương ứng .


16

Mặc dù câu trả lời được chấp nhận hiện tại hoạt động theo nghĩa là biến đường dẫn được cập nhật vĩnh viễn từ ngữ cảnh của PowerShell, nhưng thực tế nó không cập nhật biến môi trường được lưu trữ trong sổ đăng ký Windows.

Để đạt được điều đó, rõ ràng bạn cũng có thể sử dụng 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

Thêm thông tin trong bài đăng trên blog Sử dụng PowerShell để sửa đổi đường dẫn môi trường của bạn

Nếu bạn sử dụng tiện ích mở rộng cộng đồng PowerShell, lệnh thích hợp để thêm đường dẫn vào đường dẫn biến môi trường là:

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

12

Tất cả các câu trả lời cho thấy một sự thay đổi vĩnh viễn có cùng một vấn đề: Chúng phá vỡ giá trị đăng ký đường dẫn.

SetEnvironmentVariablebiến REG_EXPAND_SZgiá trị %SystemRoot%\system32 thành REG_SZgiá trị của C:\Windows\system32.

Bất kỳ biến nào khác trong đường dẫn cũng bị mất. Thêm những cái mới bằng cách sử dụng %myNewPath%sẽ không hoạt động nữa.

Đây là tập lệnh Set-PathVariable.ps1mà tôi sử dụng để giải quyết vấn đề này:

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

Tôi giải thích vấn đề chi tiết hơn trong một bài đăng trên blog .


Nếu đây là: $ newPath = $ newPath -replace ";;", ";" ?
Joe Johnston

8

Điều này đặt đường dẫn cho phiên hiện tại và nhắc người dùng thêm nó vĩnh viễn:

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

Bạn có thể thêm chức năng này vào hồ sơ mặc định của mình, ( Microsoft.PowerShell_profile.ps1), thường được đặt tại %USERPROFILE%\Documents\WindowsPowerShell.


6

Dựa trên câu trả lời của @Michael Kropat Tôi đã thêm một tham số để thêm đường dẫn mới vào PATHbiến hiện có và kiểm tra để tránh thêm đường dẫn không tồn tại:

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

Như Jonathan Leaders đã đề cập ở đây , điều quan trọng là chạy lệnh / tập lệnh nâng cao để có thể thay đổi các biến môi trường cho 'máy' , nhưng việc chạy một số lệnh nâng cao không phải thực hiện với Tiện ích mở rộng cộng đồng, vì vậy tôi muốn để sửa đổi và mở rộng câu trả lời của JeanT theo cách nào đó, việc thay đổi các biến máy cũng có thể được thực hiện ngay cả khi chính tập lệnh không chạy được nâng cao:

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

Hầu hết các câu trả lời không giải quyết UAC . Điều này bao gồm các vấn đề UAC.

Lần đầu tiên cài đặt Tiện ích mở rộng cộng đồng PowerShell: choco install pscxthông qua http://chocolatey.org/ (bạn có thể phải khởi động lại môi trường shell của mình).

Sau đó kích hoạt pscx

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

Sau đó sử dụng Invoke-Elevated

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

4

Đề nghị của tôi là cái này:

Tôi đã thử nghiệm điều này để thêm C:\oracle\x64\binvào biến môi trường Pathvĩnh viễn và điều này hoạt động tốt.

$ENV:PATH

Cách đầu tiên đơn giản là làm:

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

Nhưng sự thay đổi này không phải là vĩnh viễn. $env:pathsẽ mặc định trở lại như trước đây ngay sau khi bạn đóng thiết bị đầu cuối PowerShell và mở lại. Đó là bởi vì bạn đã áp dụng thay đổi ở cấp phiên chứ không phải ở cấp nguồn (là cấp đăng ký). Để xem giá trị toàn cầu của $env:path, hãy làm:

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

Hay cụ thể hơn:

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

Bây giờ để thay đổi điều này, đầu tiên chúng ta nắm bắt đường dẫn gốc cần được sửa đổi:

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

Bây giờ chúng ta xác định đường dẫn mới sẽ trông như thế nào. Trong trường hợp này, chúng tôi đang nối thêm một thư mục mới:

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

Lưu ý: Hãy chắc chắn rằng $newpathvẻ ngoài bạn muốn nó trông như thế nào. Nếu không, sau đó bạn có thể làm hỏng hệ điều hành của bạn.

Bây giờ áp dụng giá trị mới:

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

Bây giờ hãy thực hiện một kiểm tra cuối cùng rằng nó trông giống như cách bạn mong đợi:

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

Bây giờ bạn có thể khởi động lại thiết bị đầu cuối PowerShell của mình (hoặc thậm chí khởi động lại máy) và thấy rằng nó không quay trở lại giá trị cũ.

Lưu ý thứ tự của các đường dẫn có thể thay đổi để nó theo thứ tự bảng chữ cái, vì vậy hãy đảm bảo bạn kiểm tra toàn bộ dòng. Để dễ dàng hơn, bạn có thể chia đầu ra thành các hàng bằng cách sử dụng dấu chấm phẩy làm dấu phân cách:

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

3

Mở PowerShell và chạy:

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

1

Trong PowerShell, người ta có thể điều hướng đến thư mục biến môi trường bằng cách nhập:

Set-Location Env:

Điều này sẽ đưa bạn đến thư mục Env:>. Từ trong thư mục này:

Để xem tất cả các biến môi trường, gõ:

Env:\> Get-ChildItem

Để xem một biến môi trường cụ thể, gõ:

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

Để đặt biến môi trường, gõ:

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

Để loại bỏ một biến môi trường, gõ:

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

Thông tin thêm có trong Giới thiệu về Biến môi trường .


0

Tôi đã cố gắng tối ưu hóa mã của SBFMichael một chút để làm cho nó nhỏ gọn hơn.

Tôi đang dựa vào kiểu ép buộc của PowerShell nơi nó tự động chuyển đổi chuỗi thành giá trị enum, vì vậy tôi đã không xác định từ điển tra cứu.

Tôi cũng đã rút ra khối thêm đường dẫn mới vào danh sách dựa trên một điều kiện, để công việc đó được thực hiện một lần và được lưu trữ trong một biến để sử dụng lại.

Sau đó, nó được áp dụng vĩnh viễn hoặc chỉ cho Phiên tùy thuộc vào $PathContainertham số.

Chúng ta có thể đặt khối mã trong một hàm hoặc tệp ps1 mà chúng ta gọi trực tiếp từ dấu nhắc lệnh. Tôi đã đi với 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;

Tôi làm một cái gì đó tương tự cho một 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;

Cho đến nay, họ dường như làm việc.


0

Chỉ các câu trả lời đẩy giá trị vào sổ đăng ký mới ảnh hưởng đến thay đổi vĩnh viễn (vì vậy phần lớn các câu trả lời trên chuỗi này, bao gồm cả câu trả lời được chấp nhận, không ảnh hưởng vĩnh viễn đến Path).

Hàm sau hoạt động cho cả Path/ PSModulePathvà cho User/ Systemloại. Nó cũng sẽ thêm đường dẫn mới vào phiên hiện tại theo mặc định.

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"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.