PowerShell, ActiveDirectory and the elusive Filter parameter

Page content

When searching for users in Active Directory using PowerShell, the ActiveDirectory module is often one of the first things that comes in to mind. The module has been around for quite som time now but there is one problem that many users still stumbles on, the Filter parameter. There are basically three methods for searching after a user with Get-ADUser.

tl;dr;** This article explains how use the -Filter parameter when searching AD, if you just want the answer, skip down to the **Solution.

Using the Identity parameter

When searching for a specific user where a key property is known, the Identity parameter works well. It accepts the value for one of the following properties:

  • DistinguishedName
  • GUID (objectGUID)
  • SID (objectSID)
  • SAM AccountName (sAMAccountName)

Using the LDAPFilter parameter

The LDAPFilter parameter accepts an LDAP query string. The syntax for LDAP queries is quite comprehensive and well documented. However, getting started with LDAP filters can be a bit of a struggle and involves understanding bitflags to filter on some properties, e.g. enabled users.

The example below shows how to find all enabled users with an LDAP filter. Not something that is easy to understand for someone not used to LDAP filters.

Get-ADUser -LdapFilter ‘(!userAccountControl:1.2.840.113556.1.4.803:=2)'

Using the Filter parameter

The third option when searching the AD with PowerShell is to use the Filter parameter. This parameter accepts a filter using the PowerShell Expression Language, a syntax most PowerShell users should be very comfortable with. But none the less, this is something I often see people struggling with.

When using a new command for the first time, most users turn to Get-Help. Let’s have a look:

So far so good, but let’s have a look at one of the examples bit further down:

Get-ADUser -Filter {mail -like “*”}

This is where it usually goes wrong. The filter parameter accepts only a string and in this example we’re giving it a script block? In this specific example that works, but we need to really understand why it works before we can use this technique. Lets start from the beginning.

Parameter type

Each parameter on a command has a specific type, this means that PowerShell will convert the input given to the parameter to this object type. This conversion is called casting. Let’s have a look at the Filter parameter again:

The text marked in red shows that the Filter parameter is of type String, meaning that before the Get-ADUser even gets the filter we have specified, PowerShell will convert it to a string (cast it to a string). We can actually perform that conversion ourselves to see what Get-ADUser will see. This is how:

[string] {mail -like “*”}

No surprises there. We get a string that contains ‘mail -like “*”‘. But quite often we want to search for a specific mail address. A specific address stored in a variable. Let’s try again:

$mail = ‘simon@domain.com'

[string] {mail -like $mail}

This is where things usually goes wrong. If we convert a scriptblock to a string, variables won’t be replaced with their values and we will search for a user that has the mail address of $mail, which isn’t even a valid email! We probably won’t find anything.

Solution

Even if it sometimes works to use a scriptblock as value for the -Filter parameter, make a habit of always using a string. It will be converted to a string anyway. If you are uncertain how to build the string, here are a few starting tips:

  • Use double quoted strings Using double quotes (“) around the filter will expand any variable typed inside the string.
  • Use single quotes (‘) around any value in the filter Inside a double quoted string, single quotes can be used just like any other character.
  • If in doubt, save the filter in a variable and write it to the screen.

Let’s have a look at an example using these tips.

$Name = ‘Simon'

$Filter = ” Name -Like ‘$Name*’ ”

Write-Verbose -Message “Using filter: [$Filter]” -Verbose

$User = Get-ADUser -Filter $Filter

Here I have the variable $Name containing a name I want to search for. In a real world scenario this variable is probably assigned a value somewhere higher up in the script.

On the second line I create a filter string and assigns it to the variable $Filter. I’ve added an extra space both in the start and end of the string just to make it easier to read, these won’t make a difference. Note the single quotes around the value.

Line three writes a verbose message showing my filter in clear text, this way I can make sure that the filter looks as I intended it to. Once I’m done with my script I can remove the -Verbose from Write-Verbose and the message will only show if my script is run with -Verbose.

Line four runs Get-ADUser with my filter and assigns the result to $User. Jobs done!

 

Searching for objects in Active Directory using PowerShell is really simple, but unfortunately there are some examples out there that might throw you on the wrong path. If in doubt, stay with the tree simple tips and you’re off to a good start.