{"id":64893,"date":"2007-05-10T22:09:00","date_gmt":"2007-05-10T22:09:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/05\/10\/how-can-i-determine-the-topmost-ou-for-an-active-directory-object\/"},"modified":"2007-05-10T22:09:00","modified_gmt":"2007-05-10T22:09:00","slug":"how-can-i-determine-the-topmost-ou-for-an-active-directory-object","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-determine-the-topmost-ou-for-an-active-directory-object\/","title":{"rendered":"How Can I Determine the Topmost OU For an Active Directory Object?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"> \n<P>Hey, Scripting Guy! Given a distinguished name, how can I determine the \u201ctopmost\u201d OU?<BR><BR>&#8212; HF<\/P><IMG height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\"><\/A> \n<P>Hey, HF. You know, as he was driving in to work this morning, the Scripting Guy who writes this column heard an advertisement for a series of adult education courses being offered by a local community college. As you might expect, this commercial pointed out that taking these courses will make you smarter and help you get a better job; what was interesting, though, is that the ad also implied \u2013 slyly \u2013 that taking these courses will make it easier for to pick up girls (or guys). In other words, not only will education make you smarter, but it will make you more attractive as well.<\/P>\n<P>Oddly enough, that caused the Scripting Guy who writes this column to reflect back on his college days. One of the first college classes this Scripting Guy ever took was Astronomy 101. (It was also one of the best classes he ever took, and to this day he still wonders why he didn\u2019t take any <I>more<\/I> astronomy classes, or maybe even become an astronomer.) During one class the instructor noted that \u201cThe obliquity of the ecliptic is 23\u00bd degrees.\u201d He paused for a moment and then added, \u201cIf you remember nothing else from this course remember that. People will think you\u2019re pretty sexy if you know that the obliquity of the ecliptic is 23\u00bd degrees.\u201d<\/P>\n<P>As it turns out, the Scripting Guy who writes this column <I>did<\/I> remember that the obliquity of the ecliptic is 23\u00bd degrees. (Actually it\u2019s a tiny bit less than that, but that\u2019s close enough, especially for a column that\u2019s supposed to be about system administration scripting.) So did it work, do people think that the Scripting Guy who writes this column is pretty sexy? Let\u2019s put it this way: not everything you learn in college turns out to be true.<\/P>\n<P>Not by a long shot.<\/P>\n<P>In other words, we can\u2019t promise you that a little knowledge will make you more attractive. However, it <I>will<\/I> help you determine the topmost OU for an Active Directory object:<\/P><PRE class=\"codeSample\">Set objSysInfo = CreateObject(&#8220;ADSystemInfo&#8221;)\nstrDN = objSysInfo.UserName<\/p>\n<p>arrDN = Split(strDN, &#8220;,&#8221;)<\/p>\n<p>For i = UBound(arrDN) to 0 Step -1\n    If Left(arrDN(i), 3) = &#8220;OU=&#8221; Then\n        arrOU = Split(arrDN(i), &#8220;=&#8221;)\n        Wscript.Echo arrOU(1)\n        Exit For\n    End If\nNext\n<\/PRE>\n<P>Before we begin explaining the script let\u2019s take a minute to explain the scenario. We have the distinguished name for an object (say, a user account). That\u2019s going to look something like this:<\/P><PRE class=\"codeSample\">cn=Ken Myer,OU=Level4,OU=Level3,OU=Level2,OU=Level1,DC=fabrikam,DC=com\n<\/PRE>\n<P>As you can see, the Ken Myer account resides in the Level4 OU. Level4, in turn, is a child OU of Level3, which is a child OU of Level2, which is a child OU of Level1. (In a distinguished name the item to the right is always a parent of the item to the left.) Level1 also happens to be the \u201ctopmost\u201d OU; it\u2019s not a child of any other OU. This is the OU that we need to identify.<\/P>\n<P>Now, in a <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/dec05\/hey1220.mspx\"><B>previous column<\/B><\/A> we showed you how to identify the \u201cgrandparent\u201d OU for a given container. We can\u2019t use that approach here simply because we aren\u2019t sure how many levels we need to go up in order to find the topmost OU. Well, OK, if you want to get technical we <I>could<\/I> use that approach, albeit with a few modifications; however, we think we came up with a solution that\u2019s a little bit easier to implement.<\/P>\n<P>Of course, none of these approaches are of much use unless we have a <B>distinguishedName<\/B> attribute to work with. To take care of that problem, and for illustration purposes, we\u2019ve used this block of code to grab the distinguished name of the logged-on user:<\/P><PRE class=\"codeSample\">Set objSysInfo = CreateObject(&#8220;ADSystemInfo&#8221;)\nstrDN = objSysInfo.UserName\n<\/PRE>\n<P>All we\u2019re doing here is creating an instance of the <B>ADSystemInfo<\/B> object, an object that retrieves information about the logged-on user and his or her computer. (And before you ask, sorry: the ADSystemInfo object can only be used locally. That means this script <I>can\u2019t<\/I> be readily-modified to retrieve information about the user logged on to a remote computer. But don\u2019t despair; in an upcoming edition of <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/tnmag\/archive.mspx\"><B>TechNet Magazine<\/B><\/A> we\u2019ll discuss that very issue.) After creating the ADSystemInfo object we then assign the value of the <B>UserName<\/B> property to the variable strDN. And guess what? The value of the UserName property just happens to be the distinguished name of the logged-on user:<\/P><PRE class=\"codeSample\">cn=Ken Myer,OU=Level4,OU=Level3,OU=Level2,OU=Level1,DC=fabrikam,DC=com\n<\/PRE>\n<P>That\u2019s nice, isn\u2019t it? Except for one thing: how the heck do we determine the topmost OU given a value like that?<\/P>\n<P>There are, admittedly, different ways of doing this. For various reasons (simplicity being the primary reason) we decided to start out by using the <B>Split<\/B> function to turn this distinguished name into an array named arrDN:<\/P><PRE class=\"codeSample\">arrDN = Split(strDN, &#8220;,&#8221;)\n<\/PRE>\n<P>By splitting the string on the comma we end up with an array consisting of the following items:<\/P><PRE class=\"codeSample\">cn=Ken Myer\nOU=Level4\nOU=Level3\nOU=Level2\nOU=Level1\nDC=fabrikam\nDC=com\n<\/PRE>\n<P>As you probably know, in a distinguished name the topmost OU will always be the OU nearest the domain components (the <I>DC=<\/I> things). In this case, it\u2019s the Level1 OU that\u2019s nearest the domain components: cn=Ken Myer,OU=Level4,OU=Level3,OU=Level2,<B>OU=Level1<\/B>,DC=fabrikam,DC=com. So is there an easy way to determine which OU is nearest the domain components? You bet there is:<\/P><PRE class=\"codeSample\">For i = UBound(arrDN) to 0 Step -1\n<\/PRE>\n<P>What we\u2019ve done here is set up a For Next loop to loop through all the items in the array arrDN. But this isn\u2019t your ordinary For Next loop, one that starts with the first item in the array and works its way towards the last item. Instead, we\u2019re starting with the <I>last<\/I> item in the array (something we can determine using the <B>UBound<\/B> function) and working our way backwards towards the first item. In our example, we have an array with 7 items; that means that the last item in the array has an index number of 6. (Because the first item in an array is 0 the last item will always be the total number of items minus 1.) That means we\u2019re going to start out with the item that has the index number 6. What do we do when we\u2019re done with that item? That\u2019s easy: we\u2019ll then look at item 5; that\u2019s what the <B>Step -1<\/B> parameter is for. We\u2019ll continue doing this until we\u2019ve disposed of item 0; at that point our loop will be complete, and we\u2019ll have looked at each and every item in the array.<\/P>\n<TABLE class=\"dataTable\" id=\"EPF\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. OK, to be completely accurate, we probably won\u2019t look at <I>all<\/I> the items in the array. But we\u2019ll explain that in just a second.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Inside the loop we start out by checking to see if the first three characters in the item happen to be <B>OU=<\/B>. That\u2019s what we use this line of code, and the <B>Left<\/B> function, for:<\/P><PRE class=\"codeSample\">If Left(arrDN(i), 3) = &#8220;OU=&#8221; Then\n<\/PRE>\n<P>In our example item 6 (the first item we look at) is this: <I>DC=com<\/I>. Are the first three letters in <I>DC=com<\/I> equal to our target value (OU=)? No, they aren\u2019t. Therefore, we loop around and check the next item in the array, <I>DC=fabrikam<\/I>. Do we have a match? Nope. And so we loop around and check the <I>next<\/I> item: <I>OU=Level1<\/I>. What do you know: we\u2019ve got ourselves a winner!<\/P>\n<P>Having found the topmost OU we\u2019re now practically done; in fact, if we wanted to, we could simply echo back the value <I>OU=Level1<\/I> and call it good. However, we decided to get rid of the <I>OU=<\/I>, just to make things a little neater and cleaner. That\u2019s what we do here:<\/P><PRE class=\"codeSample\">arrOU = Split(arrDN(i), &#8220;=&#8221;)\nWscript.Echo arrOU(1)\n<\/PRE>\n<P>In the first line above we use the Split function to create another array named arrOU. This time we split the value on the equals sign (=), yielding an array with these two items:<\/P><PRE class=\"codeSample\">OU=\nLevel1\n<\/PRE>\n<P>And then in line 2 we echo back the value of the second item in the array:<\/P><PRE class=\"codeSample\">Level1\n<\/PRE>\n<P>At that point we truly <I>are<\/I> finished. Consequently, we call the <B>Exit For<\/B> statement to exit our For Next loop and <I>then<\/I> call it good. That should be all you need, HF, at least when it comes to determining the topmost OU of an Active Directory object. <\/P>\n<P>Incidentally, the Scripting Guy who writes this column <I>was<\/I> a little disappointed to discover that learning that the obliquity of the ecliptic was 23\u00bd degrees didn\u2019t make him more attractive and desirable. On the other hand, back when the Scripting Guy who writes this column first started college people still believed that the Sun revolved around the Earth. All things considered, he was just happy that no one tried burning him at the stake for claiming that the obliquity of the ecliptic was 23\u00bd degrees. <\/P>\n<TABLE class=\"dataTable\" id=\"EUH\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. What if someday he changes his mind and <I>wants<\/I> to be burned at the stake? No problem; there are plenty of people here at Microsoft who would be more than happy to help him out with that.<\/P><\/TD><\/TR><\/TBODY><\/TABLE><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! Given a distinguished name, how can I determine the \u201ctopmost\u201d OU?&#8212; HF Hey, HF. You know, as he was driving in to work this morning, the Scripting Guy who writes this column heard an advertisement for a series of adult education courses being offered by a local community college. As you might [&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,5],"class_list":["post-64893","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-ous","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! Given a distinguished name, how can I determine the \u201ctopmost\u201d OU?&#8212; HF Hey, HF. You know, as he was driving in to work this morning, the Scripting Guy who writes this column heard an advertisement for a series of adult education courses being offered by a local community college. As you might [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64893","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=64893"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64893\/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=64893"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=64893"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=64893"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}