{"id":68183,"date":"2006-01-13T15:08:00","date_gmt":"2006-01-13T15:08:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/01\/13\/how-can-i-list-all-the-sub-ous-in-an-ou\/"},"modified":"2006-01-13T15:08:00","modified_gmt":"2006-01-13T15:08:00","slug":"how-can-i-list-all-the-sub-ous-in-an-ou","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-list-all-the-sub-ous-in-an-ou\/","title":{"rendered":"How Can I List All the Sub-OUs in an OU?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>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.<BR><BR>&#8212; JE<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, JE. If you\u2019re the least bit familiar with this column then you know that we Scripting Guys love to answer questions that involve searching Active Directory. That\u2019s 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 <I>Tales from the Script<\/I> series <A href=\"http:\/\/null\/technet\/scriptcenter\/resources\/tales\/sg0405.mspx\"><B>Dude, Where\u2019s My Printer?<\/B><\/A> If you\u2019ve been playing along at home and if you picked January 13<SUP>th<\/SUP> as the first day in the year 2006 that the Scripting Guys would tackle a question involving Active Directory search, well, congratulations: you\u2019re a winner.<\/P>\n<TABLE id=\"EFD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. 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 <I>that<\/I>? Oh, right: we did. Um, yes, yes, explaining how an Active Directory search script works <I>does<\/I> exceed the scope of this column; it has <I>nothing<\/I> to do with the Scripting Guys being lazy. No, nothing at all \u2026. <I>(Editor\u2019s Note: Editing for accuracy: It has <\/I>everything<I> to do with the Scripting Guys being lazy.)<\/I><\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Now, to be fair, we don\u2019t <I>have<\/I> 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 <A href=\"http:\/\/null\/technet\/scriptcenter\/guide\/sas_vbs_kove.mspx\" target=\"_blank\"><B>recursive function<\/B><\/A>. In general, though, recursive functions are not only difficult to write but also difficult to visualize and understand. We\u2019re simple guys, and we find Active Directory search scripts much simpler to deal with. Consequently, that\u2019s the route we took:<\/P><PRE class=\"codeSample\">On Error Resume Next<\/p>\n<p>Const ADS_SCOPE_SUBTREE = 2<\/p>\n<p>Set objConnection = CreateObject(&#8220;ADODB.Connection&#8221;)\nSet objCommand =   CreateObject(&#8220;ADODB.Command&#8221;)\nobjConnection.Provider = &#8220;ADsDSOObject&#8221;\nobjConnection.Open &#8220;Active Directory Provider&#8221;\nSet objCommand.ActiveConnection = objConnection<\/p>\n<p>objCommand.Properties(&#8220;Page Size&#8221;) = 1000\nobjCommand.Properties(&#8220;Searchscope&#8221;) = ADS_SCOPE_SUBTREE <\/p>\n<p>objCommand.CommandText = _\n    &#8220;SELECT ADsPath FROM &#8216;LDAP:\/\/ou=finance,dc=fabrikam,dc=com&#8217; WHERE &#8221; &amp; _\n        &#8220;objectCategory=&#8217;organizationalUnit'&#8221;  \nSet objRecordSet = objCommand.Execute<\/p>\n<p>objRecordSet.MoveFirst\nDo Until objRecordSet.EOF\n    Wscript.Echo objRecordSet.Fields(&#8220;ADsPath&#8221;).Value\n    objRecordSet.MoveNext\nLoop\n<\/PRE>\n<P>This might look a bit intimidating to newcomers, but most of this script is boilerplate; it\u2019s the same code you\u2019ll find in almost every Active Directory search script. Because of that we\u2019re 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 <B>ADODB.Connection<\/B> object is used for then we recommend you take a look at our two-part <I>Tales from the Script<\/I> series <A href=\"http:\/\/null\/technet\/scriptcenter\/resources\/tales\/sg0405.mspx\"><B>Dude, Where\u2019s My Printer?<\/B><\/A><\/P>\n<P>Oh, right: we <I>did<\/I> mention that already, didn\u2019t we?<\/P>\n<P>Here\u2019s the code of interest:<\/P><PRE class=\"codeSample\">objCommand.CommandText = _\n    &#8220;SELECT ADsPath FROM &#8216;LDAP:\/\/ou=finance,dc=fabrikam,dc=com&#8217; WHERE &#8221; &amp; _\n        &#8220;objectCategory=&#8217;organizationalUnit'&#8221;\n<\/PRE>\n<P>What we\u2019re doing here is selecting the ADsPath attribute for all organizational units found in the Finance OU in fabrikam.com. How do we <I>know<\/I> that we\u2019re getting back the organizational units found in the Finance OU in fabrikam.com (and only those organizational units)? Two reasons: First, we know we\u2019re going to get back only OUs because our Where clause limits us to items that have an <B>objectCategory<\/B> equal to organizationalUnit. That\u2019s going to filter out user accounts, groups, print queues, and anything else that might be found in Active Directory.<\/P>\n<P>That makes sense. But how do we know we\u2019ll get back only those OUs that can be found in the Finance OU? Because, in this script, we don\u2019t start our search in the Active Directory root; instead we start it in the Finance OU itself: <B>LDAP:\/\/ou=finance, dc=fabrikam, dc=com<\/B>. That means we\u2019re going to search only the Finance OU and any other containers found in that OU; we aren\u2019t 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\u2019d target our query like so:<\/P><PRE class=\"codeSample\">objCommand.CommandText = _\n    &#8220;SELECT AdsPath FROM &#8216;LDAP:\/\/ou=West Coast,ou=USA,dc=fabrikam,dc=com&#8217; WHERE &#8221; &amp; _\n        &#8220;objectCategory=&#8217;organizationalUnit'&#8221;\n<\/PRE>\n<P>Pretty straightforward.<\/P>\n<P>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 <I>we<\/I> picked before answering another Active Directory search question. The Scripting Guys cheat? Say it isn\u2019t so! ((Although, knowing the Scripting Guys, we\u2019d probably lose the office pool even if we <I>did<\/I> cheat. Which helps explain why we all live in Redmond, WA rather than, say, Monte Carlo.) <\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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.&#8212; JE Hey, JE. If you\u2019re the least bit familiar with this column then you know that we Scripting Guys love to answer questions that involve searching Active Directory. That\u2019s because we never [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[7,43,3,8,5],"class_list":["post-68183","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-ous","tag-scripting-guy","tag-searching-active-directory","tag-vbscript"],"acf":[],"blog_post_summary":"<p>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.&#8212; JE Hey, JE. If you\u2019re the least bit familiar with this column then you know that we Scripting Guys love to answer questions that involve searching Active Directory. That\u2019s because we never [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68183","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=68183"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68183\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=68183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=68183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=68183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}