2012-01-23 29 views
5

Tôi đang chỉnh sửa PATH trên một số máy chủ W2k3 trong PowerShell để chuyển đổi một số đường dẫn nhất định với khoảng trắng thành 8,3 tương đương. Sau một số phép biến đổi regex, tôi chạy hai lệnh sau:Làm cách nào để xử lý mở rộng biến Windows PATH khi được đặt từ PowerShell?

# Set the path for this process 
$env:PATH = $path 
# Set the path for the Machine 
[System.Environment]::SetEnvironmentVariable('PATH', $path,[System.EnvironmentVariableTarget]::Machine) 

Sau khi chạy chúng, đường dẫn được thay đổi theo cách tôi không có ý định. % SystemRoot% được mở rộng đồng đều thành C: \ Windows. Tôi không thể nhìn thấy điều này báo hiệu sự khải huyền, nhưng tôi muốn giữ% SystemRoot%, vì vậy tôi đã bỏ qua cho đến khi tôi nhận% SystemRoot% xuất hiện trong đường dẫn một lần nữa, nhưng khi tôi làm đường dẫn không còn mở rộng và không còn công trinh. Echo đường dẫn tại CLI trả về một chuỗi chưa được mở rộng (điều này là sai) và các lệnh trong SystemRoot không còn có thể được tìm thấy nữa.

Nếu sau đó tôi thêm mục nhập rỗng vào Đường dẫn ";;", mà không thay đổi bất kỳ văn bản nào khác trong PATH, nó bắt đầu hoạt động chính xác.

Vì vậy, câu hỏi của tôi là làm thế nào để thay đổi đường dẫn lập trình bằng cách sử dụng PowerShell để không muck up mở rộng biến trong đường dẫn?

+0

2 ghi chú: 1) Tôi mở CLI mới cho mỗi bài kiểm tra và 2) đường dẫn tôi đọc từ $ env: PATH được mở rộng, vì vậy tôi đọc c: \ windows và thay đổi giá trị thành% SystemRoot theo cách thủ công % sau đó đẩy giá trị đó trở lại môi trường. – codepoke

+0

Có gì trong '$ path' khi bạn đặt nó thành' PATH'? – manojlds

+0

Nó khác nhau trên mọi máy chủ, nhưng ...;% SystemRoot% \ system32;% SystemRoot%;% SystemRoot% \ System32 \ Wbem;% SystemRoot% \ system32 \ WindowsPowerShell \ v1.0; ... là một thành phần trên tất cả của họ. Khi tôi đọc $ path, nó được mở rộng thành c: \ Windows trong suốt quá trình đọc. Tôi phải mở rộng giá trị mở rộng với tương đương biến của nó trước khi thiết lập nó. Giá trị $ path đó với các biến sẽ không mở rộng trở lại trừ khi tôi chạm vào nó một cách thủ công thông qua hộp thoại thuộc tính. – codepoke

Trả lời

6

Theo như tôi có thể nói, bạn không thể làm điều này với phương pháp [Environment]::SetEnvironmentVariable() và bạn không thể thực hiện việc này với nhà cung cấp đăng ký. Tuy nhiên bạn có thể truy cập vào hệ thống đường dẫn env var trong registry bằng cách sử dụng lớp Microsoft.Win32.RegistryKey như vậy:

 
C:\PS> $key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment', $true) 
C:\PS> $path = $key.GetValue('Path',$null,'DoNotExpandEnvironmentNames') 
C:\PS> $path 
...;%systemroot%\System32\WindowsPowerShell\v1.0\ 
C:\PS> $key.SetValue('Path', $path + ';%Windir%\Symbols', 'ExpandString') 
C:\PS> $key.Dispose() 

này sẽ cho phép bạn lưu các PATH cập nhật và duy trì các biến xuất hiện trong giá trị Path.

+0

Tuyệt vời, Keith. Cám ơn bạn một lần nữa. – codepoke

+0

FYI, kịch bản có lẽ nên được đặt trong một thử/cuối cùng và bên trong cuối cùng làm một Vứt bỏ trên khóa registry. –

+0

Bạn biết đấy, tôi gần như hỏi về điều này, nhưng kể từ khi kịch bản của tôi là ngắn và mọi biến mất đi ngay lập tức, tôi đã không đổ mồ hôi nó. Nhưng kể từ khi bạn đưa nó lên. :-) .NET 4.0 bao gồm phương thức Dispose() thủ công mà bạn gọi, nhưng 2.0 thì không. Làm thế nào tôi nên vứt bỏ chìa khóa mà không có phương thức Dispose()? – codepoke

Các vấn đề liên quan