Thursday, July 26, 2012

Unable to Filter Get-ADUser Based on Distinguished Name

When you are using the Get-AD* cmdlets to generate a list of users or other objects, it is a best practice to use the Filter parameter. When you use the Filter parameter, you pass a filter directly to Active Directory when you run the cmdlet. This is more efficient than retrieving a large list of objects and then filtering them with Where-Object.

I was working through a query with Get-ADUser that would obtain a list of all disabled users from Active Directory except for two or three OUs. To do this, I was trying to use the Filter parameter as shown below.
Get AD-User -Filter {(enabled -eq $false) -and (distinguishedname -notlike "*cn=users,dc=contoso,dc=com)}

Looks good right? Unfortunately, the filtering based on the distinguished name didn't work. It turns out that you cannot use wildcards when filtering based on the distinguished name. I also tried using the CanonicalName property, but it is a calculated property generated by Get-ADUser. So, CanonicalName cannot be used for a filter. The answer is to use Where-Object.
Get AD-User -Filter * | Where-Object {($_.enabled -eq $false) -and ($_.distinguishedname -notlike "*cn=users,dc=contoso,dc=com)}

**Note that a standard OU would start with ou= rather than cn=. Both the Users container and the Computers container are technically not OUs.

11 comments:

  1. Thanks for the note. The only work around for this problem I could find was to jack [code]| Where-Object {DistinguishedName -notlike "*OU=Blah*"}[/code] on the end of the like.

    ReplyDelete
  2. Thank you for posting this. This was driving me crazy so it's nice to know it wasn't a flaw in my script.

    ReplyDelete
  3. It was making me scratch my head as well. WFT Microsoft!?

    ReplyDelete
  4. A time saver, thanks.

    ReplyDelete
  5. Thank you for posting this. I just ran into this same issue and you saved me some time so I am going to try to return the favor. Depending on how large your environment is. If you move the enabled check to the filter it will run a lot faster as it will only search the where clause on the result of the disabled accounts and not all users.

    Get AD-User -Filter {enabled -eq $false} | Where-Object {($_.distinguishedname -notlike "*cn=users,dc=contoso,dc=com)}

    ReplyDelete
    Replies
    1. Thank-you. That is an excellent improvement for larger environments.

      Delete
  6. You could also use -Filter {enabled -eq $false} -SearchBase "CN=Users,DC=contoso,DC=com". No need for wildcards...

    ReplyDelete
    Replies
    1. In the example above, it's excluding the user accounts in Users OU. That was the tricky part. If wanting to query only users within an OU (and subtree), your method is preferred.

      Delete
  7. Thanks for the one-liner!

    ReplyDelete