PowerShell’da System.DirectoryServices.ResultPropertyCollection‘ı Anlamak

PowerShell ile çalışırken ve Active Directory’yi sorgularken, System.DirectoryServices.ResultPropertyCollection‘dan özelliklere erişmeye çalışırken karmaşık bir davranışla karşılaşabilirsiniz. Bu yazıda, bir DirectorySearcher aracılığıyla bilgi alırken karşılaşılan yaygın bir sorunu çözeceğiz—özellikle iki farklı çıkışın neden beklenmedik sonuçlar ürettiğini. Sorunu, kök nedenini keşfedelim ve bunu etkili bir şekilde nasıl çözeceğinizi öğrenelim.

Sorun

Active Directory’de bilgisayar nesnelerini bulmak için DirectorySearcher sınıfını kullanan bir PowerShell betiği kurdunuz, ancak çıktınızda tutarsızlıklar ile karşılaşıyorsunuz. İşte kodunuzun basitleştirilmiş bir replikasyonu:

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher  
$objSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry  
$objSearcher.Filter = ("(objectclass=computer)")  
$computers = $objSearcher.findall()  

Bilgisayarların isimlerini yazdırmaya çalıştığınızda, aşağıdaki iki çıktıyı gözlemliyorsunuz:

$computers | %{
    "Server name in quotes $_.properties.name" 
    "Server name not in quotes " + $_.properties.name 
}

Ve sonra:

$computers[0] | %{"$_.properties.name"; $_.properties.name}

Sonuç, alıntı içinde yer aldığında özellik için bir tür ismi gösteriyor (System.DirectoryServices.SearchResult.properties.name), ancak alıntı içinde olmadığında bir değer gösteriyor. Bu nüansı anlamak, PowerShell’de özellik alımını ustalıkla kavramanın anahtarıdır.

Neden Çıktılar Farklılık Gösteriyor?

Tutarsızlık, PowerShell’in değişkenleri ve özellikleri dizelerde nasıl değerlendirdiğinden kaynaklanmaktadır. $_‘yi bir dizede kullandığınızda, PowerShell bunu bütün bir nesne olarak görür:

  • Tırnaklı Bağlam: ";" gibi bir dize içinde kullanıldığında, örneğin "Server name in quotes $_.properties.name", PowerShell özelliği değerlendirmez; bunun yerine nesnenin ToString yöntemini referans alır ve bu durumda özellik tür adını varsayılan olarak döndürür.

  • Tırnaksız Bağlam: Tersine, tırnaksız kullandığınızda, örneğin "Server name not in quotes " + $_.properties.name, PowerShell önce özelliği değerlendirir ve ardından bunu dizeye birleştirir. Böylece, tür adını değil, özelliğin içinde depolanan gerçek değeri alır.

Çıktıyı Düzeltme

Bir alıntı dizesi içinde hedeflenen özellik değerini almak için, alt ifade sözdizimini kullanarak değerlendirmeyi açıkça başlatabilirsiniz:

"Server name in quotes $($_.properties.name)"  

Bu $() kullanımı, PowerShell’e içindeki öğeyi değerlendirmesi için talimat verir ve ardından dizeyi işlemeye devam eder, böylece beklediğiniz doğru çıktıyı elde edersiniz.

Sonuç Özellik Koleksiyonunu Keşfetmek

Unutmayın, ResultPropertyCollection ile çalışırken, bir özellikler koleksiyonu ile uğraşmaktasınız. PowerShell komut satırından doğrudan nesne modelini keşfetmek her zaman mümkündür. Örneğin, $computers[0].properties‘i Get-Member komutuna yönlendirmek, mevcut üyeler ve özellikler hakkında bilgi verir:

$computers[0].properties | Get-Member

Burada Values özelliğini görebilirsiniz; bu, özelliğin değerlerinin bir ICollection‘ını alır. Bu keşif, anlayışınızı artırır ve özellikler arasında daha etkili bir şekilde dolaşmanıza olanak tanır.

Sonuç

PowerShell ve Active Directory’deki System.DirectoryServices ile çalışırken, dize değerlendirmenin nesnelere ve bunların özelliklerine nasıl etki ettiğini kavramak çok önemlidir. Bu özelliklerin erişildiği farklı bağlamları tanıyacak olursanız, kafa karışıklığını önleyebilir ve ihtiyaç duyduğunuz bilgiyi beklediğiniz biçimde alabilirsiniz.

ResultPropertyCollection gibi karmaşık PowerShell yapılarında gezinmek ilk başta zor görünebilir, ancak pratik ve daha derin anlayışla, bu durumun, betik yazım yolculuğunuzda ikinci bir doğa haline geldiğini göreceksiniz.