Microsoft PowerShell – Filtering Object – Bölüm 6. Filtering işlemi ile Pipeline üzerinde tutulacak objeler belirlenir. Bu belirleme sırasında kriterler kullanılır. Bu kriterlerin yazılmasında da karşılaştırma operatörlerinden faydalanılır.
Objelerin Property’lerine göre operatörler kullanılarak karşılaştırma yapılır, karşılaştırma sonucunda döndürülen değer “True” ise obje tutulur, “False” ise obje silinir.
PowerShell üzerinde kullanılabilecek karşılaştırma operatörleri aşağıdaki gibidir;
- -eq : Eşittir (equal to)
- -ne : Eşit Değildir (not equal to)
- -gt : Büyüktür (greater than)
- -lt : Küçüktür (less than)
- -le : Küçük yada Eşit (less than or equal to)
- -ge : Büyük yada Eşit (greater than or equal to)
Bu operatörlerin hepsi String karşılaştırma değerleri için Case Sensitive değildir. Yani büyük küçük harf’e aldırış etmez. Eğer String değerler için Case Sensitive bir karşılaştırmaya ihtiyaç duyulursa -ceq ve -cne operatörleri kullanılabilir.
Bu operatörlerin yanında PowerShell üzerinde daha gelişmiş operatörler de vardır. Örneğin;
- -in ve -contains operatörleri belirli bir objenin bir collection içerisinde bulunup bulunmadığını sorgular.
- -as operatörü bir objenin belirli tipte olup olmadığına göre işlem yapmayı sağlar.
- -match ve cmatch operatörü String değeri Regular Expressions ile karşılaştırır.
Resim-1
PowerShell içerisinde karşılaştırmaları tersine yapan birçok operatör de mevcuttur.
Örn: -notlike , -notin
Karşılaştırma operatörleri PowerShell konsoluna direkt olarak yazılabilir.
Resim-2
Resim-3
PowerShell mimarisinde filtreleme yapılırken Where-Object (yada kısaca Where) komutu kullanılır. Where-Object komutu ile filtreleme iki şekilde yapılır.
Basic Filtering Syntax
Where-Object komutu kullanılarak basit filtreleme işlemi yapıldığında komutu karşılaştırılacak Property, operatör ve karşılaştırılacak değer takip eder. Bunun sonucunda da kritere uyan değerler tutulurken diğerleri silinirler.
Basic filtering seçeneğinde komutun yazılması ve okunması diğerine göre oldukça kolaydır.
Get-Service | Where Status –eq Running
Resim-4
Burada dikkat edilecek nokta karşılaştırılacak Property isimlerinin düzgün yazılmasıdır. Herhangi bir kısaltma karşılaştırma durumunda kabul edilemez, çünkü kesinlik belirtmek gerekir.
Sınırlılıkları
Basic Syntax ile sadece bir karşılaştırma yapılabilir. Yani kriter içerisinde sadece tek bir koşul belirtilebilir.
Örneğin bir servis için hem durumu “running” hem de başlangıç modu “automatic” olanlar listelenmek istendiğinde bu işlem Basic Syntax ile yapılamaz.
Bir diğer sınırlılık ise Property’lere ait metodlara Basic Syntax ile ulaşılamaz. Örneğin isim uzunluğu 5 karakterden fazla olan Process’ler listelenmek istenip aşağıdaki komut yazılırsa, komut istenilen sonucu vermez.
Resim-5
Yukarıdaki örnekte name Property’si System.String objesini kullanır ve System.String objesi Length Property’sine sahiptir. Ancak bu değeri Basic Sytanx ile almak mümkün değildir.
Advanced Filtering Syntax
Where-Object Advanced Syntax ile Script filtreleme kullanır. Bu Script içerisinde builtin olarak gelen $PSItem ($_.) değişkeni kullanılarak pipe edilmiş obje referans olarak gösterilir. Komut tarafından Pipe edilen her bir obje için bu Script bir kez çalıştırılır. Eğer sonuç “True” dönerse obje listelenir. Eğer sonuç “False” dönerse obje Pipeline’dan silinir.
Aşağıdaki iki komut için sonuç aynıdır. Bunlardan birisi Basic diğeri Advanced Syntax ile yazılmıştır.
Get-Service | Where name -eq BITS
Get-Service | Where -FilterScript { $PSItem.Name -eq ‘BITS’}
Resim-6
-FilterScript parametresi durumsal olarak kullanılır. Kullanılması zorunlu değildir.
Bazen filtreleme komutlarında Where kelimesi yerine “?” kullanılabilir. Bu Where kelimesinin Aliası’dır. Yani yukarıda kullanılan Advanced Syntax’a ait komutun Alias’lar kullanılarak yazılım şekli aşağıdaki gibidir.
Get-Service | Where -FilterScript { $PSItem.Name -eq ‘BITS’}
Get-Service | ? {$_.Name -eq ‘BITS’}
Resim-7
BITS kelimesini yazarken ‘BITS’ şeklinde tırnak içine almak gereklidir. Aksi taktirde PowerShell BITS kelimesinde komut arama yolunu seçecektir.
Multiple Criteria
Advanced syntax kullanmanın en önemli nedeni birden çok kriter belirtebilmektir. Bunu yaparken Script bloğu içerisinde –and ve –or mantıksal operatörlerini kullanır.
Aşağıdaki ifadede Where koşulu içerisine EventID ve Source Property’lerine ilişkin koşullar kontrol edilmiştir ve bunun sonucuna göre kritere uygun objeler listelenmiştir.
Get-EventLog -LogName Application -Newest 1000 | Where {$_.EventID -eq 1000 -and $_.Source -eq ‘Application Error’}
Resim-8
Birden çok koşullu ifade yazarken yapılan bazı yanlışlarda vardır. Bunlardan en sık yapılanları aşağıdaki gibidir.
Get-Process | Where {$_.CPu -gt 30 -and VM -lt 9000 }
Buradaki hata Property’yi direk olarak yazmaktır. Where koşulu içerisinde bu şekilde Basic Syntax’ta olduğu gibi yazım yapılamaz. $PSItem.VM yada $_.VM şeklinde yazılması gerekir.
Yine bir diğer çok karşılaşılan yazım hatası da aşağıdaki gibidir.
Get-Service | Where {$_.Status -eq ‘Running’ -or ‘Stopped’ }
Bu komut çalıştırıldığında hata vermez ancak tutarlı ve doğru bir listeleme de yapmaz. Bunun nedeni direkt olarak –or ifadesinden sonra ‘Stopped’ düzgün bir karşılaştırma ifadesi değildir. Komutun aşağıdaki şekilde yazılması gerekir.
Get-Service | Where {$_.Status -eq ‘Running’ -or $_.Status -eq ‘Stopped’ }
True ve False Değeri barındıran Property’ler
Where koşulu ile filtreleme yaparken amaç belirtilen koşul yada koşullara göre True yada False değeri döndürmektir. Çoğunlukla da bu durum mantıksal operatörler yardımıyla sağlanır. (-eq,-ne vb..) Bazen koşul içerisinde kullanılan Property’ler kendiliğinden True yada False değerine sahip olabilirler. (boolean data tipinde olabilirler). Bu gibi durumlarda herhangi bir çift taraflı karşılaştırmaya gerek olmadan Property değerlerinin True yada False oluşu sorgulanabilir.
Aşağıdaki komutta olduğu gibi CanShutdown Property’sinin değerinin True olup olmadığı direk mantıksal operatörler kullanılıp $True değişkenine eşitlenerek karşılaştırılabilir.
Get-Service | Where {$_.CanShutdown -eq $True }
Resim-9
Ya da alternatif olarak Where koşulu içerisine herhangi bir mantıksal operatör kullanmadan direkt Property yazılarak da karşılaştırma yapılabilir. Bunun nedeni CanShutdown Property’sinin hali hazırda True yada False değeri taşıyor olmasıdır.
Get-Service | Where {$_.CanShutdown}
Resim-10
Koşulun tam zıttı yazılmak istenirse komut aşağıdaki gibi düzenlenmelidir. –not mantıksal operatörü Where koşulunun içerisine eklenmelidir.
Get-Service | Where { -not $_.CanShutdown }
Resim-11
-not operatörü dönen True değerini False ile, False değerini True ile değiştirir.
Son olarak Basic Syntax’ta sadece Property’nin kendisine erişiliyordu. Property’e ait bir metod koşul içerisinde kullanılmak istendiğinde PowerShell hata veriyordu.
Advanced Syntax’ta bu konuda bir limit yoktur. Property’lere ait tüm metodlara erişilebilir ve Where koşulu içerisinde kriter olarak kullanılabilir.
Örneğin isminin uzunluğu 10 karakterden fazla olan servisler listelenmek istendiğinde aşağıdaki gibi bir komut kolaylıkla çalıştırılabilir.
(bu komut Basic Syntax ile denendiğinde hata alınmıştı)
Get-Service | Where {$_.Name.Length -gt 10 }
Resim-12
Filtreleme işlemi yaparken göz önünde bulundurulması gereken bir diğer durum ise performanstır. Veri büyük olduğunda filtreleme performansı göz önünde bulundurmak gibi bir durum söz konusudur.
Bu durumla ilgili filtreleme sırasında dikkat edilmesi gereken birkaç önemli nokta bulunmakta.
- Örneğin aşağıdaki iki örnek komut aynı objeleri listelerler. Ancak ikinci komut birinciye göre daha hızlıdır. Çünkü filtreleme yapılmadan önce Pipeline üzerinden istenmeyen blokları siler. Böylece filtreleme işlemi daha az obje üzerinden yapılmış olur.
Birinci komut bütün objeleri sıraladığı için, sıralama için harcadığı efor diğerine göre daha fazladır.
Get-Service | Sort-Object -Property name | Where -FilterScript { $PSItem.Status -eq ‘Running’ }
Get-Service | Where -FilterScript { $PSItem.Status -eq ‘Running’ } | Sort-Object -Property name
- Örneğin bazı komutlarda filtreleme işlemi yapmadan önce komut ile birlikte parametre kullanarak komut çıktısı limitlendirilebilir.
Örneğin Get-ChildItem komutu kullanılarak bir dizindeki dosya ve klasörler listelenebilir. Bu komutun PSIsContainer parametresi vardır ve bu parametre dosyalar için False değerini döndürür.
Get-Childıtem komutu ile dosyalar listelenmek istendiğinde aşağıdaki komut kullanılabilir.
Get-ChildItem | Where {-not $PSItem.PSIsContainer}
Fakat yinede bu performans bakımından çok efektif bir yöntem değildir. Get-ChildItem komutunun –File parametresi vardır ve bu parametre kullanılarak filtreleme en başta yapılırsa komut daha efektif çalışır.
Get-ChildItem -File *
- Son olarak örneğin ismi svc ile başlayan servisler listelenmek istendiğinde aşağıdaki komut kullanılabilir. Fakat bu komut yine tüm objeleri önce get edip sonrasında bunlar içerisinde ismi wi ile başlayan servisleri filtreleyecektir.
Get-Service | Where name -Like wi*
Bunun yerine aşağıdaki komutun kullanılması daha efektif olur.
Get-Service -Name wi*
Bir sonraki makalede görüşmek üzere.
Bu konuyla ilgili sorularınızı alt kısımda bulunan yorumlar alanını kullanarak sorabilirsiniz.
Referanslar
DMOC
TAGs : Microsoft PowerShell, Filtering Object, powershell nedir, powershell komutlari, powershell filtering, powershell ornekleri, powershell kullanim ornekleri, powershell filtering object