Cuma Eğlencesi - PowerShell ile Özel Gruplama


Geçen gün PowerShell Facebook grubunda bir soruyu yanıtlıyordum. Bu kişi Active Directory'den veri alıyor ve sonuçları iş gereksinimlerini karşılayacak şekilde düzenlemeye çalışıyordu. Benim önerim Group-Object ve özel bir gruplama özelliğini kullanmaktı. Group-Object'e aşina olduğunuzu varsayıyorum. Bir özellik adı belirtebilirsiniz ve gelen nesneler özellik değerine göre gruplandırılır. Bu, işleri kovalar halinde organize etmenin kullanışlı bir yoludur. Bazen sadece sonuçları gruplandırmak istersiniz, bazen de her grupla bir şeyler yapmak istersiniz. Ancak Group-Object ile ilgili tüm yardımı ve örnekleri okursanız (okudunuz, değil mi?), özel bir gruplama oluşturmanın bir yolu olduğunu görürsünüz. Bunun nasıl çalıştığına dair size birkaç örnek vereceğimi düşündüm.

Özel Özellik Komut Dosyası Bloğu

Grup Nesnesini kullanmanın bu geleneksel yolu, bir komutu ona yönlendirmek ve gelen nesneleri bir özellik adına göre düzenlemektir.

Get-Childitem c:\scripts -file | Group-Object -Property Extension

Bunun nasıl çalıştığını görmek için bu örneği bilgisayarınızdaki herhangi bir yolla deneyebilirsiniz. Ancak PowerShell büyülüdür veya en azından esnektir ve yoktan yarattığınız bir şeyi gruplandırabilirsiniz. Her nesneyi temsil etmek için bir komut dosyası bloğu ve $_ kullanabilirsiniz. Bu, Select-Object'te özel özellikler oluşturmak için kullanılan konseptin aynısıdır. Ancak bu durumda Grup Nesnesi komut dosyası bloğunun adlandırılmasına gerek yoktur. İşte basit bir örnek.

Get-ChildItem c:\scripts -file -Recurse -exclude *.exe | 
Group-Object -property {$_.LastWriteTime.Year}

Dosyalar LastWriteTime özelliğinin Year özelliğine göre gruplandırılacaktır.

Gördüğünüz gibi bir süredir bu senaryo yazma işini yapıyorum. Bu örnek basittir ve konsola yazılması kolaydır. Ancak komut dosyası bloğuna koyabileceğiniz şeylerin bir sınırı yoktur. Burada arkadaşımın Active Directory ile yapmaya çalıştığı şeye benzeyen daha karmaşık bir gruplama var.

Get-ChildItem c:\scripts -file | Group-Object -Property {
    switch -Regex ($_.extension) {
        "\.(ps(d|m)?1(xml)?)$" {"PowerShell"}
        "\.(bat|cmd|sh)$" {"Shell"}
        "\.(txt|md)$" {"Text"}
        "\.(xml|json|csv|yml)$" {"Data"}
        "\.(zip|rar)$" { "Archive"}
        Default {"Other"}
    }
}

Gruplandırma bir Switch ifadesi kullanıyor. Bu konuda bilginiz yoksa about_Switch yardım konusunu okuyarak başlayın. Extension özelliğine bakıyorum ve normal ifade karşılaştırması yapıyorum. Switch ifadelerinin bu kadar karmaşık olması gerekmez ama bu öyle. Dosya bir kalıpla eşleşiyorsa çıktı değeri karşılık gelen dize olacaktır.

Alternatif olarak If/ElseIF ifadesini kullanabilirsiniz. Switch deyiminde PowerShell'in olası tüm eşleşmeleri test ettiğini unutmayın. Bu davranışı istemiyorsanız ve birden fazla eşleşme alma ihtimaliniz varsa Break'i kullanabilirsiniz.

"\.(ps(d|m)?1(xml)?)$" {"PowerShell";Break}

Benim durumumda, yinelenen eşleşmeyi önlemek için normal ifade kalıplarını yazdım. Ve Varsayılan girişi gerekli olmasa da, bu şekilde gruplama yaparken onu da dahil edeceğim. Aksi takdirde gruplandırma sonucu adı boş olacaktır. Bazı durumlarda, örneğin belirli Active Directory nesnelerini gruplandırırken bir istisna oluşturulacaktır.

İşte Active Directory'yi kullanan son bir örnek. Kullanıcıları departmanlara göre daha büyük "gruplar" halinde düzenlemek istiyorum.

$Operations = "IT", "Dev", "Accounting", "Executive", "Manufacturing", "Payroll", "Quality Assurance"
$Sales = "Sales", "Marketing"
$Internal = "Physical Plant", "Development"
$Customer = "Customer Service", "Consumer Affairs", "Public Affairs"

Get-ADUser -Filter * -Properties title, department, Displayname |
Group-Object -property {
    $vars =  Get-Variable -Name "Operations", "Sales", "Internal", "Customer"
    if ($_.department) {
        foreach ($v in $vars) {
            if ($v.value -contains $_.department) {
                $class = $v.name
                Break
            }
        } #foreach      
    }
    if (-not $class) {
        $class =  "Uncategorized"
    }
    $class
} 

Departman isimlerini içeren değişkenleri tanımlıyorum. Gruplandırma, değişkenler arasında geçiş yapan ve departman adının değişkene ait olup olmadığını test eden özel bir özellik kullanır. Eğer öyleyse, değişken adını çıktı olarak kullanıyorum. Departmanı olmayan ve listemde olmayan hesapları dikkate aldığımdan değil. Bu olmadan, "Nesne referansı bir nesnenin örneğine değil" hatası alıyorum.

Özet

PowerShell ile çalışırken insanlara her zaman "boru hattındaki nesnelere" odaklanmalarını söylüyorum. Bu harika bir örnek. Elbette sahip olduğunuz nesnelerle başlayın, ancak bunun sizi nesneleri yaratıcı şekillerde kullanmaktan alıkoymasına izin vermeyin. Her zaman daha fazlasını yapma fırsatlarını arıyorum ve özel gruplandırma özellikleri PowerShell araç kutunuz için kullanışlı bir araçtır.

İlgili makaleler