Fine-Tuning Your Active Directory PowerShell Searches

Finding a group/OU intersection

PowerShell's Active Directory (AD)-related search commands (get-aduser, get-adgroupmember, search-adaccount, and so on) are some of the things that attracted me most to the new Windows Server 2008 R2 cmdlets, and that’s why I've been focusing on them for the past few months. I think it’s pretty neat to be able to run a query such as

get-aduser -f {title -eq "claims adjuster" -and manager -eq "cn=JFarkus,cn=users,dc=bigfirm,dc=com"} -searchbase "ou=Montana,dc=bigfirm,dc=com"
to retrieve all the claims adjusters at Bigfirm.com who are from the Montana OU and who have a manager with the username JFarkus. And that example took me only about 30 seconds to formulate! The hardest part was remembering that I had to use a distinguished name (DN) for a manager—and when I remember how long it took me to do something like that in VBScript, I, get a little dizzy.

I'm grateful for the power of the PowerShell cmdlets, but they can be frustrating because, really, they're nothing more than a prettier front end on LDAP queries, and so things that your intuition tells you should work—don’t (for example, searching to find the people whose managers' names begin with S.) But when you're using the get-whatever AD commands and find yourself in a corner, don't give up: Rather, just try to attack it from a different angle.

And that brings me to last's month's puzzle. How do you query AD for a group's members, but to return only the group members who also live in a particular OU? How do you find all the members of the group folks who live in the Sales OU?

Hmmm … maybe you could retrieve a group's membership with get-aduser rather than get-adgroupmember. You could slap a -searchbase parameter on the end, and you’d be in good shape. Whenever I'm up against something like this in PowerShell (“Can get-something get a property that will solve the problem?"), I go look at the attributes of the object in question. As you’ve seen before, you can get an extensive list of the attributes that user objects in PowerShell contain by typing

get-aduser -f * | gm
By doing that, I see it: MemberOf. Time to take a look at what a typical MemberOf looks like with this command:

get-aduser -f {samaccountname -eq "mark"} -pr MemberOf | ft name,memberof -auto
Recall that ft is format-table and that if you don't include -pr MemberOf in get-aduser, you won't get that attribute delivered down the pipeline. MemberOf ends up looking like {CN=Enterprise Admins,CN=Users,DC=Bigfirm,DC=com,CN=Schema Admins,CN=Users,DC=Bigfirm,DC=com… and so on, so essentially MemberOf is a comma-delimited list of the DNs of the various groups that the user named mark is a member of. (And if format-table's output is a bit too 1980s teletype for you, remember that if you have the PowerShell ISE feature installed, you can use the grid view, as in

get-aduser -f {samaccountname -eq "mark"} -pr MemberOf | ogv
and you can install the PowerShell ISE from PowerShell itself by typing ipmo servermanager and then add-windowsfeature powershell-ise, but unfortunately you'll have to close your PowerShell window and open a new one to get GridView working.)

Next, you'd try using MemberOf in a get-aduser filter. Maybe this will show us all the people in the Enterprise Admins group?

get-aduser -f {MemberOf -like "*Enterprise Admins*"}
But unfortunately that returns no results because MemberOf seems to want comparisons with exact DNs of groups, and so this returns the members of the Enterprise Admins group:

get-aduser -f {Memberof -eq "CN=Enterprise Admins,CN=Users,DC=Bigfirm,DC=com"}
Now, that retrieves the members of the Enterprise Admins group, and the only pain that it exacts is that you've got to know the DN of that or any other group. It's simple to get a list of the groups in a domain and their DNs, though:

get-adgroup -f *|ft name,distinguishedname -auto
And from there it's all cut and paste. To return to the original question—“What members of the group folks are in the Sales OU?"—you could formulate it like this:

get-aduser -f {memberof -eq "CN=Folks,CN=Users,DC=Bigfirm,DC=com"} -searchbase "ou=sales,dc=bigfirm,dc=com"
Oh, and while we're at it, you could even make that query against a Global Catalog (GC) by adding - servername:port, as a member of the AD PowerShell team pointed out to me recently. (Thanks, Saket!). Assuming you want to run the query against a DC named DC4 that was also a GC server, I could run this query:

get-aduser -f {memberof -eq "CN=Folks,CN=Users,DC=Bigfirm,DC=com"} -searchbase "ou=sales,dc=bigfirm,dc=com" -server dc4:3268
The morals of this month's story, then, are as follows: It never hurts to give an object's list of attributes another look, and never assume that you should be able to use wildcards against DNs. See you next month!

Please or Register to post comments.

IT/Dev Connections

Las Vegas
September 30th - October 4th

Paul ThurottYou'll have the opportunity to experience:
• The Microsoft
Technology Roadmap
• Office 365 Implementation
• Hyper-V Optimizing
• Windows 8 Deployment
and much more!

Come See Paul Thurrott & Rod Trent in Person!

Early Registration Now Open

Upcoming Training

Mastering System Center 2012

During over 6 hours of training you can join John Savill from your computer as he will walk you through the key components and capabilities of System Center 2012, what’s involved in using the components, and the benefit they can bring to your environment.

Register Now

Current Issue

May 2013 - The NameTranslate object is useful when you need to translate Active Directory object names between different formats, but it's awkward to use from PowerShell. Here's a PowerShell script that eliminates the awkwardness.

CURRENT ISSUE / ARCHIVE / SUBSCRIBE

Windows Forums

Get answers to questions, share tips, and engage with the Windows Community in our Forums.