Summary: Learn how to use the Filter parameter and the Windows PowerShell Expression Language on the Active Directory module cmdlets.
Hey, Scripting Guy! I do not know why you like ADSI so much. The syntax is obscure, and it makes things hard to read. Yesterday’s blog that used Get-ADComputer could have been so much better if you had left out that stupid ADSI filter. What gives, Scripting Guy? You’re not turning developer on me are you?
—JJ
Hello JJ,
Microsoft Scripting Guy, Ed Wilson, is here. No JJ, I am not turning developer on you, but Windows PowerShell is a great way to allow one to get in touch with their “inner developer.” I have been writing code for a very long time. Back when I bought my first computer (an Osborne), if I wanted a program to do something like balance a check book, I had to write it myself. It was a great way to learn programming (if somewhat error prone and slow). Since then, I have written everything from assembly (at the University) through C++. Truly and honestly though, Windows PowerShell is the most fun. Even though I can write code, I do not consider myself a developer. In my heart-of-hearts, I am an IT Pro and a hardware geek.
Reuse LDAP queries from other scripting languages
So what is the deal with using ADSI and LDAP? For one thing, it is standard. My early experience with messaging systems was all X.500 based, and from there, it is a short hop to LDAP. Familiarity with LDAP dialect permits one to easily use some of the many examples of LDAP dialect and ADO to query Active Directory on the Scripting Guys Script Repository. It is trivial to “steal” the LDAP query and plug it in to Get-ADComputer or Get-ADObject, regardless of the native language of the original script. As an example of this, consider the VBScript, Search for User Phone Numbers Beginning with 425, on the Scripting Guys Script repository. The essence of this 20 line script is shown here.
objCommand.CommandText = _
"<LDAP://dc=fabrikam,dc=com>;(&(objectCategory=User)" & _
"(telephoneNumber=425*));Name;Subtree"
I take the filter portion of the script and I end up with the following LDAP filter.
"(&(objectCategory=User)(telephonenumber=425*))”
This filter is exactly what I need when I plug it in to the LDAPFilter parameter of the Get-ADUser cmdlet. In fact, the hard part was already done when I found the LDAP dialect ADO query in the previous VBScript—not to mention the cool factor of taking a 20-line VBScript and shrinking it to a single Windows PowerShell line as shown here.
Get-ADUser -LDAPFilter "(&(objectCategory=User)(telephonenumber=425*))"
Query Active Directory without LDAP
One problem with using the filter parameter instead of an LDAP filter is having to learn a new filter syntax. (Of course, all the examples in Backus-Naur Form do not really help the average IT Pro much with this learning task). Another problem with using the filter parameter is that generally the syntax is more work than the corresponding LDAP filter. For example, the query to find users with phone numbers that begin with 425 is shown here.
Get-ADUser -Filter {(objectCategory -eq "User") -and (TelephoneNumber-like "425*")}
You can see that the syntax is similar to the LDAP filter, but it uses the Windows PowerShell operators instead of the LDAP operators. In addition, the quotation marks are required.
To rewrite the LDAP query that returns only servers, I would use the command shown here.
Get-ADComputer -Filter {(objectcategory -eq "computer") -AND (OperatingSystem -like '*server*')}
One thing to keep in mind is that the filter parameter does not support Regular Expressions in the filter. Therefore, I cannot use the following command because it generates an error.
Get-ADComputer -Filter {(objectcategory -eq "computer") -AND (OperatingSystem -match 'server')} -Properties operatingsystem
The command and the error message are shown here.
The following table lists the supported filter operators.
Operator |
Meaning |
Eq |
equal |
Le |
Less than or equal |
Ge |
Greater than or equal |
Ne |
Not equal |
Lt |
Less than |
Gt |
Greater than |
Approx. |
Approximently |
Bor |
Boolean or |
Band |
Boolean and |
Recursivematch |
Recursive match |
Like |
Wild card like |
Notlike |
Wild card not like |
And |
And |
Or |
Or |
Not |
Not |
JJ, that is all there is to using the filter parameter to query Active Directory and to not use LDAP dialect. Join me tomorrow for more Windows PowerShell cool stuff. Until then, peace.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow.
Ed Wilson, Microsoft Scripting Guy