Powershell'de karmaşık ldap filtreleriyle çalışma
Active Directory ve Powershell ile çalışırken ldap filtrelerini kullanmak, dizinde mükemmel performansla arama yapmanın harika bir yoludur. Tek sorun, ldap filtrelerinin okunmasının biraz zor olması ve bazen aralarında bazı şifreli değerlerin olduğu parantezlerin titrek bir hali gibi görünmeleridir.
Ldap filtreleri yazdığımda genellikle bunları çok satırlı girintili metin olarak yazarım; örneğin, etkinleştirilmiş ve süresi dolmak üzere ayarlanmamış tüm kullanıcıları (kişiler veya bilgisayarlar değil) aramak istediğimi varsayalım. Bir powershell betiğinde şöyle görünecektir:
$filter = '(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(|(accountExpires=0)(accountExpires=9223372036854775807))(userAccountControl:1.2.840.113556.1.4.803:=65536))'Okuması gerçekten o kadar kolay değil mi? Ancak burada bir dize kullanırsam ve onu birden çok satıra bölersem ve girinti eklersem:
$filter = @'
(&
(objectCategory=person)
(objectClass=user)
(!
(userAccountControl:1.2.840.113556.1.4.803:=2)
)
(|
(accountExpires=0)
(accountExpires=9223372036854775807)
)
(userAccountControl:1.2.840.113556.1.4.803:=65536)
)
'@Bu hala biraz karmaşık görünebilir ancak okunması çok daha kolaydır. Ne yazık ki bu format geçerli bir ldap filtresi değil, bu yüzden filtremi yazmayı bitirdiğimde tüm satır sonlarını ve onu takip eden boşlukları kaldırmam gerekiyor. Powershell ve düzenli ifadelerin gerçekten işe yaradığı yer burasıdır.
Düzenli ifade, metnin bölümlerini eşleştirmek için kullanılabilecek bir metin desenini tanımlayan bir dizedir. MSDN'de harika bir regex referansı var. Bu durumda, bir metinde, ardından sıfır veya daha fazla boşluk gelen herhangi bir satır sonu için arama yapmak ve herhangi bir eşleşmeyi hiçbir şeyle veya boş bir dizeyle değiştirmek istiyoruz. Referans sayfasına baktığımızda, n'nin yeni bir satır karakteriyle (satır sonu) ve s'nin herhangi bir boşluk karakteriyle (yani bizim boşluklarımız) eşleşeceğini görebiliriz. Ayrıca önceki öğeyle sıfır veya daha fazla eşleşecek bir niceleyici (*) vardır. Bununla birlikte, "ns*", ardından sıfır veya daha fazla boşluk gelen herhangi bir satır sonuyla eşleşecektir. Buradaki dizemize bu normal ifade modeliyle bir değiştirme eklemek, $filter değişkenimizi geçerli bir ldap filtresi haline getirecektir:
$filter = @'
(&
(objectCategory=person)
(objectClass=user)
(!
(userAccountControl:1.2.840.113556.1.4.803:=2)
)
(|
(accountExpires=0)
(accountExpires=9223372036854775807)
)
(userAccountControl:1.2.840.113556.1.4.803:=65536)
)
'@ -replace 'ns*','
'
Bu, kendi ldap filtremi yazarken harika bir küçük hiledir, ancak başka birinin yazdığı bir ldap filtresini okurken pek işe yaramayacaktır. Bunun için bir ldap filtresini dize olarak alacak ve onu daha okunabilir bir duruma yeniden biçimlendirecek küçük bir powershell betiği yazdım. Son örneğimizdeki ldap filtresinin nasıl yeniden yazıldığına dair bir örnek:
Senaryoyu Technet Galerileri'nde yayınladım.