Quick tip: human-readable LDAP filter

Whenever I work with Active Directory and I want to use pretty complex LDAP Filter to search for objects I’m after I’m tempted to use line break here and there to make whole thing easier on eyes of future reviewer (even if the only person to read the code is me “few weeks later”).

The problem is that AD won’t understand filter that looks like that:

$LDAPFilter = @'
    (&
        (name=b*)
        (givenName=b*)
    )
'@            

It won’t fail, you won’t get an error, it just won’t work. What I usually do is just use –join operator on array that looks very similar to above here-string:

$LdapFilterJoined = -join @(            
     '(&'            
        '(name=b*)'            
        '(givenName=b*)'            
    ')'            
)

Another options is just remove any whitespace from here-string that we created at first:

$FilterFixed = $LDAPFilter -replace "\s"            
([adsisearcher]$FilterFixed).FindOne()

End result in either case should be similar:

PowerShell-ADSI-LDAP-Filter-With-Replace

For simple filters it doesn’t make sense to break anything into several lines, it’s obvious what will happen anyway. But if you mix several conditions in single LDAP Filter (AND and ORs), than it’s convenient to have each group presented in clear format. E.g.:

$MonthAgo = (Get-Date).AddDays(-30).ToFileTime()            
(            
    [ADSISearcher](             
        -join @(            
            '(&'            
                '(!userAccountControl:1.2.840.113556.1.4.803:=2)'            
                '(|'            
                    '(name=b*)'            
                    '(givenName=b*)'            
                ')'            
                "(lastLogonTimeStamp>=$MonthAgo)"            
            ')'            
        )            
    )            
).FindAll()

Obviously, using single-line syntax would be as effective as this one. The only difference is than now I have no problem to tell which conditions have to be met (&) and what is optional (|).

Advertisements

5 thoughts on “Quick tip: human-readable LDAP filter

  1. How about:
    filter Remove-Whitespace { foreach ($x in (" ","`r","`n","`t")){$_ = $_.Replace($x,'') };$_}

    That way you can still use the here-string.
    $LDAPFilter = @'
    (&
    (name=b*)
    (givenName=b*)
    )
    '@ | Remove-Whitespace
    ([adsisearcher]$LDAPFilter ).FindOne()

    • Thanks for comment! 🙂
      I would say it’s similar to what I’ve did with -replace, but probably more granular.

      The problem with both approaches is that some LDAP filters can contain spaces, e.g. (name=Bartosz B*).
      If you remove spaces you will break the filter.

      And I guess it would be possible to be more smart about it and only remove spaces that are not within brackets, but not sure I would like to spent time on implementing that. 🙂

      But as always in PowerShell – your suggestion is prove that there is always several ways to skin the cat. 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s