How Can I List All the Sub-OUs in an OU?

How Can I List All the Sub-OUs in an OU?

  • Comments 3
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I list all the sub-OUs in an OU? That includes any OUs that might be in those sub-OUs.

-- JE

SpacerHey, Scripting Guy! AnswerScript Center

Hey, JE. If you’re the least bit familiar with this column then you know that we Scripting Guys love to answer questions that involve searching Active Directory. That’s because we never bother to write detailed explanations of how the scripts we show you work; instead, we just refer you to our two-part Tales from the Script series Dude, Where’s My Printer? If you’ve been playing along at home and if you picked January 13th as the first day in the year 2006 that the Scripting Guys would tackle a question involving Active Directory search, well, congratulations: you’re a winner.

Note. So is it really true that explaining how an Active Directory search script works would exceed the scope of this column? Man, who told you that? Oh, right: we did. Um, yes, yes, explaining how an Active Directory search script works does exceed the scope of this column; it has nothing to do with the Scripting Guys being lazy. No, nothing at all …. (Editor’s Note: Editing for accuracy: It has everything to do with the Scripting Guys being lazy.)

Now, to be fair, we don’t have to use an Active Directory search to retrieve a list of all the sub-OUs (and sub-sub-OUs, etc.) within a specific OU; we could achieve the same results using a recursive function. In general, though, recursive functions are not only difficult to write but also difficult to visualize and understand. We’re simple guys, and we find Active Directory search scripts much simpler to deal with. Consequently, that’s the route we took:

On Error Resume Next

Const ADS_SCOPE_SUBTREE = 2

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 

objCommand.CommandText = _
    "SELECT ADsPath FROM 'LDAP://ou=finance,dc=fabrikam,dc=com' WHERE " & _
        "objectCategory='organizationalUnit'"  
Set objRecordSet = objCommand.Execute

objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    Wscript.Echo objRecordSet.Fields("ADsPath").Value
    objRecordSet.MoveNext
Loop

This might look a bit intimidating to newcomers, but most of this script is boilerplate; it’s the same code you’ll find in almost every Active Directory search script. Because of that we’re going to focus on just one small piece of the puzzle, the SQL statement we use to query Active Directory. If you have no idea what an ADODB.Connection object is used for then we recommend you take a look at our two-part Tales from the Script series Dude, Where’s My Printer?

Oh, right: we did mention that already, didn’t we?

Here’s the code of interest:

objCommand.CommandText = _
    "SELECT ADsPath FROM 'LDAP://ou=finance,dc=fabrikam,dc=com' WHERE " & _
        "objectCategory='organizationalUnit'"

What we’re doing here is selecting the ADsPath attribute for all organizational units found in the Finance OU in fabrikam.com. How do we know that we’re getting back the organizational units found in the Finance OU in fabrikam.com (and only those organizational units)? Two reasons: First, we know we’re going to get back only OUs because our Where clause limits us to items that have an objectCategory equal to organizationalUnit. That’s going to filter out user accounts, groups, print queues, and anything else that might be found in Active Directory.

That makes sense. But how do we know we’ll get back only those OUs that can be found in the Finance OU? Because, in this script, we don’t start our search in the Active Directory root; instead we start it in the Finance OU itself: LDAP://ou=finance, dc=fabrikam, dc=com. That means we’re going to search only the Finance OU and any other containers found in that OU; we aren’t even going to take a peek anywhere else. In turn, that means anything we get back from this script has to be within the Finance OU. Suppose we wanted to find all the OUs located in the West Coast OU, which happens to be in the USA OU? Then we’d target our query like so:

objCommand.CommandText = _
    "SELECT AdsPath FROM 'LDAP://ou=West Coast,ou=USA,dc=fabrikam,dc=com' WHERE " & _
        "objectCategory='organizationalUnit'"

Pretty straightforward.

So when will the Scripting Guys tackle another Active Directory search question? Well, we thought about starting an office pool and taking bets on the next date, but then someone pointed out that we could cheat and just wait until the date we picked before answering another Active Directory search question. The Scripting Guys cheat? Say it isn’t so! ((Although, knowing the Scripting Guys, we’d probably lose the office pool even if we did cheat. Which helps explain why we all live in Redmond, WA rather than, say, Monte Carlo.)

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • What If I want the output to be in plane text? It's normally CN=Carver\,Garrett,OU=Users,OU=World Headquarters, ect....

    What I get is the above, but it has multiple people, this means taht it looks like a jumbled mess. How do you parsse through to take CN=Carver\,Garrett,Ou=Users,... ect to Carver,Garrett?

  • Diddle – you are responding to a 5 year old blog.

    Try posting in these place and you will get an answer much faster.

    social.technet.microsoft.com/.../ITCG

    www.sapien.com/.../default.asp

    What you are looking for is the CN which is just the name.

  • could you post an updated way to do this using get-adorganizationalunit?