8.10.2019

Powershell komut satırını özelleştirme

Her kabuk (shell) penceresinde olduğu gibi Powershell'de de uzunca satır çıktı üreten komutlar sonrasında komutların yazıldığı satırlar ile çıktılar birbirine karışabilir. Bunu önlemenin basit bir yolu komut satırlarını renklendirmek olabilir. Örnek olarak bu çalışmanın yapılmadığı bir Powershell penceresinde çıktı şu şekilde olur:


Ve uygun düzenlemeler sonrasında şu şekilde:


Satır genişliğindeki değişme, bu düzenlemeler sonucunda değil, bu kısmı göz ardı edelim. Odaklanmamız gereken Get-ChildItem ile başlayan satırdaki renklenme. Bunu sağlamak için öncelikle profile.ps1 dosya şu şekilde bir prompt fonksiyonu ekledim:

function Prompt
{
    $promptString = "PS " + (Get-Date -Format t) + " " + $(Get-Location) + ">"
    Write-Host $promptString -NoNewline -ForegroundColor Cyan
    return " "

}

Bunun sonucunda PS kısaltmasından hemen sonra saat ve dakikayı içeren saat bilgisi, ve dosya sistemindeki mevcut konumumu gösteren klasör yolunu renkli olarak aldım. Profile.ps1 dosyasının konumu da Belgelerim klasörümün içinde WindowsPowershell klasörünün içinde olmalıdır. Belgelerim klasörümün konumunu öğrenmek için
PS> [environment]::getfolderpath("mydocuments")
yazabilirim.

Burada yaptığım bir renklendirme de Windows 10 ile varsayılan olarak yüklü gelen PSGallery modülü PSReadLine'ı yüklemek oldu. Bunun sonucunda cmdlet'ler ile parametrelerim farklı renkli görünmeye başladı. Ayrıca kapatılmamış bir tırnak veya parantez varsa prompt'un sonundaki '>' işaretinin de rengi kırmızıya dönüşüyor. Görsel olmayan bir büyük fark da klavye kısayollarının gelmesi. cmd.exe'de var olmayan son kelimeyi silme kısayolu olarak Ctrl+Backspace varsayılan ataması geliyor. Değiştirmek için
Set-PSReadLineKeyHandler -Chord Ctrl+w -Function BackwardDeleteWord
gibi atamalar kullanılabilir.

PSReadline modülünün bir güzelliği de pencereler kapatılsa bile silinmeyen bir komut geçmişine (history)  sahip olması. Bu komut geçmişini
Get-PSReadlineOption

cmdlet'inin çıktısındaki HistorySavePath değişkeninde bulabiliriz. İlginç olan yukarı ve aşağı ok tuşlarıyla komut geçmişinde gezinmek mümkün, ama Get-History ile bu geçmişi göremiyoruz. Eğer Get-History / Invoke-History gibi komutları kullanmayı tercih ediyorsak PSReadlineHistory modülünü yükleyerek bu iki komutun eşdeğeri olan Get-PSReadlineHistory / Invoke-PSReadlineHistory gibi komutlara sahip olabiliriz. İleride bizi bekleyen bir sorun; komut geçmişinin binlerce satırdan oluşması. Bu durumda shell penceresinin açılışı çok uzun sürebilir. Bu durumlar için geliştirilen cmdlet Optimize-PSReadlinehistory. Komut geçmişinin boyutu sınırlandırılabilir, belli bir karakterden uzun olmayan komutlar silinebilir, ya da tekrarlayan komutlardan kurtulunabilir. Komut geçmişi de 

%appdata%\Microsoft\Windows\Poweshell\PSReadLine\ConsoleHost_history.txt 

dosyasında saklanır, doğrudan müdahale etmek istenirse.

BONUS: Açılan pencerenin yönetici olarak açılıp açılmadığını başlık çubuğunda yazan Administrator kelimesinden anlayabiliriz. Ama ayrıca komut satırında da bununla ilgili bir belirteç görmek istersek bu ayrımı yapabilmek için şu yöntem kullanılabilir:

if ((whoami /all | select-string S-1-16-12288) -ne $null
{
     Write-Host "#" -ForegroundColor White -BackgroundColor DarkGreen -NoNewline
}
else
{
    Write-Host ">" -ForegroundColor Green -NoNewline
}
Bu şekilde yönetici ayrıcalıklarıyla açılan pencerenin komut satırında koyu yeşil fon üzerine beyaz bir # işareti, normal kullanıcı yetkileriyle açılanda ise yeşil bir > işareti görüntülenebilir.

Şu sayfadaki
if ((New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator))
{
  Write-Output "Elevated."
}
else
{
  Write-Output "Not elevated."
}

örneği gibi başka alternatifler de var. Kırmızı ile yazılan if satırı bölünmeden tek satır olmalı, ya da uygun bir bölme yöntemi ile bölünebilir.

Ek 2020-07-29: Windows 8.1 üzerinde sorun yaşamadım ama aynı yapılandırma ile Windows 10 üzerinde ufak bir sorunum vardı. PSReadLine ile gelen ve komut satırında eksik bir tırnak veya parantez olması durumunda ">" işaretini kırmızı yapan özellik çalışmıyordu. Sonradan anladım ki bunu sağlamak için Prompt fonksiyonunun içine

Set-PSReadLineOption -PromptText "> "

eklenmeli.
---
https://docs.microsoft.com/en-us/powershell/module/psreadline/?view=powershell-6

Hiç yorum yok: