Saya telah menemukan bahwa pengaturan PATH variabel lingkungan hanya mempengaruhi lama command prompt. PowerShell tampaknya memiliki berbagai pengaturan lingkungan. Bagaimana saya mengubah variabel lingkungan untuk PowerShell (v1)?
Catatan:
Saya ingin membuat perubahan permanen, jadi saya don't harus mengatur hal itu setiap kali saya menjalankan PowerShell. Tidak PowerShell memiliki profil file? Sesuatu seperti Bash profil pada Unix?
Perubahan lingkungan yang sebenarnya variabel yang dapat dilakukan oleh
menggunakan env: namespace / drive
informasi. Misalnya, ini
kode akan memperbarui variabel lingkungan path:
$env:Path = "SomeRandomPath"; (replaces existing path)
$env:Path += ";SomeRandomPath" (appends to existing path)
Ada cara untuk membuat pengaturan lingkungan permanen, tetapi
jika anda hanya menggunakan mereka dari PowerShell, it's mungkin
jauh lebih baik untuk menggunakan profil anda untuk memulai
pengaturan. Pada startup, PowerShell akan menjalankan file .ps1
file yang ditemukan di WindowsPowerShell
direktori di bawah
Folder My Documents. Biasanya anda memiliki profil.ps1
file yang sudah ada. Jalan di komputer saya
C:\Users\JaredPar\Documents\WindowsPowerShell\profile.ps1
Anda juga dapat memodifikasi pengguna/sistem variabel lingkungan permanen (yaitu akan terus-menerus di shell restart) dengan berikut:
Memodifikasi variabel lingkungan sistem
[Environment]::SetEnvironmentVariable
("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)
Memodifikasi variabel lingkungan pengguna
[Environment]::SetEnvironmentVariable
("INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User)
Penggunaan dari komentar - tambahkan ke sistem variabel lingkungan
[Environment]::SetEnvironmentVariable(
"Path",
[Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\bin",
[EnvironmentVariableTarget]::Machine)
String berdasarkan solusi ini juga memungkinkan jika anda don't ingin menulis jenis
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", "Machine")
Dari PowerShell prompt:
setx PATH "$env:path;\the\directory\to\add" -m
Maka anda harus melihat teks:
SUCCESS: Specified value was saved.
Restart sesi anda, dan variabel yang akan tersedia. setx
juga dapat digunakan untuk mengatur sewenang-wenang variabel. Jenis setx /?
pada prompt untuk dokumentasi.
Sebelum bermain-main dengan jalan anda dalam cara ini, pastikan bahwa anda menyimpan salinan jalur yang ada dengan melakukan $env:jalan >> a.out
di PowerShell prompt.
Seperti JeanT's jawaban, saya ingin sebuah abstraksi sekitar menambahkan ke jalan. Tidak seperti JeanT's jawaban yang saya butuhkan untuk berjalan tanpa interaksi pengguna. Perilaku lain yang saya cari:
$env:Jalur
agar perubahan berlaku dalam sesi saat iniDalam kasus itu's berguna, di sini adalah:
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 ';'
}
}
Check out saya gist untuk yang sesuai Hapus-EnvPath
fungsi.
Meskipun saat ini jawaban yang diterima bekerja dalam arti bahwa variabel path akan secara permanen diperbarui dari konteks PowerShell, itu doesn't benar-benar memperbarui variabel lingkungan yang tersimpan di registri Windows.
Untuk mencapai itu, anda dapat dengan jelas menggunakan PowerShell juga:
$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
Informasi lebih lanjut di posting blog Menggunakan PowerShell untuk Memodifikasi Lingkungan Path
Jika anda menggunakan PowerShell masyarakat ekstensi yang tepat perintah untuk menambahkan path variabel lingkungan path:
Add-PathVariable "C:\NewFolderToAddToTheList" -Target Machine
Semua jawaban yang menunjukkan perubahan permanen memiliki masalah yang sama: Mereka melanggar jalur nilai registri.
SetEnvironmentVariable
ternyata REG_EXPAND_SZ
nilai %SystemRoot%\system32
menjadi REG_SZ
nilai C:\Windows\system32
.
Variabel lain di jalan yang hilang juga. Menambahkan yang baru menggunakan %myNewPath%
won't bekerja lagi.
Berikut ini's script Set-PathVariable.ps1
yang saya gunakan untuk mengatasi masalah ini:
[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
}
Saya menjelaskan masalah ini secara lebih rinci dalam blog post.
Ini menetapkan jalan untuk sesi saat ini dan meminta pengguna untuk menambahkannya secara permanen:
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'
}
}
Anda dapat menambahkan fungsi ini ke profil default anda, (Microsoft.PowerShell_profile.ps1
), biasanya terletak di %USERPROFILE%\Documents\WindowsPowerShell
.
Bangunan di @Michael Kropat's jawaban saya menambahkan parameter untuk menambahkan jalan baru yang ada `JALAN'variable dan cek untuk menghindari penambahan non-jalan yang ada:
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 ';'
}
}
}
}
Sebagai Jonathan Pemimpin disebutkan di sini, adalah penting untuk menjalankan perintah/script tinggi untuk dapat mengubah variabel lingkungan untuk 'mesin', tapi menjalankan beberapa perintah ditinggikan doesn't harus dilakukan dengan Masyarakat Ekstensi, jadi saya'd seperti untuk memodifikasi dan memperluas JeanT's jawaban dalam sebuah cara, yaitu mengubah mesin variabel juga dapat dilakukan bahkan jika script itu sendiri isn't berjalan tinggi:
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
}
}
Kebanyakan jawaban aren't menangani UAC. Ini mencakup UAC masalah.
Pertama menginstal PowerShell Masyarakat Ekstensi: choco menginstal pscx
via http://chocolatey.org/ (anda mungkin harus me-restart anda shell environment).
Kemudian mengaktifkan pscx
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser #allows scripts to run from the interwebs, such as pcsx
Kemudian menggunakan Memanggil-Tinggi
Invoke-Elevated {Add-PathVariable $args[0] -Target Machine} -ArgumentList $MY_NEW_DIR
Saran saya adalah yang satu ini:
Saya telah diuji ini untuk menambah C:\oracle\x64\bin
untuk variabel lingkungan Path
secara permanen dan ini bekerja dengan baik.
$ENV:PATH
Cara pertama adalah hanya untuk melakukan:
$ENV:PATH=”$ENV:PATH;c:\path\to\folder”
Tapi perubahan ini tidak permanen. $env:path
akan default kembali ke apa itu sebelumnya segera setelah anda menutup anda PowerShell terminal dan membuka kembali lagi. Itu karena anda telah menerapkan perubahan di tingkat sesi dan tidak di sumber tingkat (yang merupakan tingkat registry). Untuk melihat nilai global $env:jalan
, lakukan:
Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH
Atau lebih spesifik:
(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path
Sekarang untuk mengubah ini, pertama kita menangkap jalan asli yang perlu diubah:
$oldpath = (Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).path
Sekarang kita mendefinisikan apa yang baru jalan harus terlihat seperti. Dalam hal ini kami menambahkan folder baru:
$newpath = “$oldpath;c:\path\to\folder”
Catatan: pastikan bahwa $newpath
terlihat bagaimana yang anda inginkan untuk melihat. Jika tidak, maka anda bisa merusak OS.
Sekarang menerapkan nilai baru:
Set-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH -Value $newPath
Sekarang lakukan salah satu final memeriksa bahwa itu tampak seperti cara yang anda harapkan ke:
(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PATH).Path
Sekarang anda dapat me-restart anda PowerShell terminal (atau bahkan reboot mesin) dan lihat bahwa itu tidak rollback untuk nilai lama lagi.
Catatan pemesanan jalan dapat berubah sehingga dalam urutan abjad, jadi pastikan anda memeriksa seluruh baris. Untuk membuatnya lebih mudah, anda dapat membagi output ke dalam baris dengan menggunakan semi-colon sebagai pembatas:
($env:path).split(“;”)
Saya mencoba untuk mengoptimalkan SBF's dan Michael's kode sedikit untuk membuatnya lebih kompak.
Saya mengandalkan PowerShell's jenis paksaan di mana hal itu secara otomatis mengkonversi string ke enum nilai-nilai, jadi saya didn't mendefinisikan lookup kamus.
Saya juga ditarik keluar blok yang menambah jalur baru ke daftar yang didasarkan pada kondisi, sehingga pekerjaan ini dilakukan sekali dan disimpan dalam sebuah variabel untuk digunakan kembali.
Hal ini kemudian diterapkan secara permanen atau hanya untuk Sesi tergantung pada $PathContainer
parameter.
Kita dapat menempatkan blok kode dalam fungsi atau ps1 file yang kita panggil langsung dari command prompt. Aku pergi dengan 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;
Saya melakukan sesuatu yang mirip untuk 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;
Sejauh ini, mereka tampaknya untuk bekerja.
Dalam PowerShell, satu dapat menavigasi ke variabel lingkungan direktori dengan mengetik:
Set-Location Env:
Ini akan membawa anda ke Env:> direktori. Dari dalam direktori ini:
Untuk melihat semua variabel lingkungan, ketik:
Env:\> Get-ChildItem
Untuk melihat lingkungan tertentu variabel, ketik:
Env:\> $Env:<variable name>, e.g. $Env:Path
Untuk mengatur variabel lingkungan, ketik:
Env:\> $Env:<variable name> = "<new-value>", e.g. $Env:Path="C:\Users\"
Untuk menghapus variabel lingkungan, ketik:
Env:\> remove-item Env:<variable name>, e.g. remove-item Env:SECRET_KEY
Informasi lebih lanjut di Tentang Variabel Lingkungan.