{"id":71173,"date":"2004-10-21T17:25:00","date_gmt":"2004-10-21T17:25:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2004\/10\/21\/how-can-i-determine-the-ou-a-user-account-belongs-to\/"},"modified":"2004-10-21T17:25:00","modified_gmt":"2004-10-21T17:25:00","slug":"how-can-i-determine-the-ou-a-user-account-belongs-to","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-determine-the-ou-a-user-account-belongs-to\/","title":{"rendered":"How Can I Determine the OU a User Account Belongs To?"},"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! How do I determine the OU a user account belongs to?<BR><BR>&#8212; CO<\/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, CO. Ah, yes: the OU a user belongs to. No doubt a lot of you are thinking, \u201cWell, there\u2019s probably an OU property of some kind in Active Directory that gives you that information. All you have to do is locate the user account, and then get the value of the OU property.\u201d<\/P>\n<P>That makes so much sense that &#8211; as you might have guessed &#8211; it\u2019s not the way things work. As it turns out, there is no OU property (or anything equivalent) in Active Directory. But don\u2019t fret. That doesn\u2019t mean we can\u2019t determine the user\u2019s OU; it just means we &#8211; gasp! &#8211; have to work a little harder to do so.<\/P>\n<P>For the purposes of this column, we\u2019re assuming that you don\u2019t know the user\u2019s distinguished name; after all, with a distinguished name like CN=kenmyer,OU=Finance,DC-fabrikam,DC=com, well, even a Scripting Guy can figure out which OU the user belongs to. So we\u2019ll assume that all you know is the user\u2019s SAM account name, the name he or she typically uses to log on to the domain.<\/P>\n<P>If you <I>do<\/I> know the SAM account name you\u2019re in luck; that\u2019s because these names must be unique in the Active Directory forest. Therefore, we can find this user by doing an Active Directory search:<\/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 distinguishedName FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE objectCategory=&#8217;user&#8217; &#8221; &amp; _\n        &#8220;AND sAMAccountName=&#8217;kenmyer'&#8221;\nSet objRecordSet = objCommand.Execute<\/p>\n<p>objRecordSet.MoveFirst\nDo Until objRecordSet.EOF\n    Wscript.Echo objRecordSet.Fields(&#8220;distinguishedName&#8221;).Value\n    objRecordSet.MoveNext\nLoop\n<\/PRE>\n<P>As we\u2019ve noted before, there\u2019s quite a bit involved in carrying out an Active Directory search, even though the script isn\u2019t really all that long or all that complicated. For more information, check out this <A href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=25562\"><B>Scripting Guys\u2019 Webcast<\/B><\/A>.<\/P>\n<P>Without going into any detail, what we\u2019ve done here is search fabrikam.com for the user with the sAMAccountName <B>kenmyer<\/B>, As soon as we find him we echo his distinguished name (the distinguishedName attribute). Because that\u2019s in the form CN=kenmyer,OU=Finance,DC=fabrikam,DC=com, we can look at the results and determine the user\u2019s OU.<\/P>\n<P>But the truth is, we\u2019re too lazy to look at the user\u2019s distinguished name; we want the script to do that for us. So let\u2019s make a slight modification to our Do loop. Here\u2019s the modified code; we\u2019ll explain how it works in a second.<\/P><PRE class=\"codeSample\">Do Until objRecordSet.EOF\n    strDN = objRecordSet.Fields(&#8220;distinguishedName&#8221;).Value\n    arrPath = Split(strDN, &#8220;,&#8221;)\n    intLength = Len(arrPath(1))\n    intNameLength = intLength &#8211; 3\n    Wscript.Echo Right(arrPath(1), intNameLength)\n    objRecordSet.MoveNext\nLoop\n<\/PRE>\n<P>Whoa! But don\u2019t panic; this actually makes sense. We start, again, by getting the value of the user\u2019s distinguished name; as we already know, this will be something like <B>CN=kenmyer,OU=Finance,DC=fabrikam,DC=com<\/B>.<\/P>\n<P>We store this value in the variable strPath, then use the VBScript Split command to, well, split strPath into elements of an array. When we use the Split command and split on the comma (that is, we indicate that the comma is our delimiter, the character that separate the individual items in the string), we end up with an array that consists of the following elements:<\/P><PRE class=\"codeSample\">CN=kenmyer \nOU=Finance\nDC=fabrikam\nDC=com\n<\/PRE>\n<P>We know that the second element in the array (and the second element in an array always has an index number of 1) is the OU where the user account resides. That means that, to get the name of the OU, we just need to take the second element (<B>arrPath(1)<\/B>)and then get rid of the OU=.<\/P>\n<P>Can we do that? Of course we can. We use the Len function to determine the number of characters in element 0 of our array. Remember, the value is <B>OU=Finance<\/B>, so the number of characters is 10.<\/P>\n<P>Next we subtract 3 from the number of characters. Why? Well, we want to get rid of OU=, and OU= has three characters. Subtracting 3 from 10 leaves us with 7, which means we now know that the actual name of the OU &#8211; <B>Finance<\/B> &#8211; is 7 characters long.<\/P>\n<P>Now &#8211; finally &#8211; we use the Right function to grab the last 7 characters in the string; in other words, we start at the <B>e<\/B> in <B>OU=Finance<\/B> and move back 7 characters. And guess what? You got it: the last 7 characters in <B>OU=Finance<\/B> just happen to be <B>Finance<\/B>, the name of the OU where the user account lives. Hey, we did it!<\/P>\n<P>Here\u2019s the revised script that searches Active Directory and reports back the OU where the user account resides. <\/P><PRE class=\"codeSample\">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 distinguishedName FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; \u201c &amp; _\n        &#8220;WHERE objectCategory=&#8217;user&#8217; &#8221; &amp; _\n            &#8220;AND sAMAccountName=&#8217;kenmyer'&#8221;\nSet objRecordSet = objCommand.Execute<\/p>\n<p>objRecordSet.MoveFirst\nDo Until objRecordSet.EOF\n    strDN = objRecordSet.Fields(&#8220;distinguishedName&#8221;).Value\n    arrPath = Split(strDN, &#8220;,&#8221;)\n    intLength = Len(arrPath(1))\n    intNameLength = intLength &#8211; 3\n    Wscript.Echo Right(arrPath(1), intNameLength)\n    objRecordSet.MoveNext\nLoop\n<\/PRE><BR>\n<DIV>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"0\" width=\"100%\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"\"><A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/oct04\/hey1021.mspx#top\"><IMG height=\"9\" alt=\"Top of page\" src=\"http:\/\/www.microsoft.com\/technet\/mnplibrary\/templates\/MNP2.Common\/images\/arrow_px_up.gif\" width=\"7\" border=\"0\"><\/A><A class=\"topOfPage\" href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/oct04\/hey1021.mspx#top\">Top of page<\/A><\/TD><\/TR><\/TBODY><\/TABLE><\/DIV><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How do I determine the OU a user account belongs to?&#8212; CO Hey, CO. Ah, yes: the OU a user belongs to. No doubt a lot of you are thinking, \u201cWell, there\u2019s probably an OU property of some kind in Active Directory that gives you that information. All you have to do [&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-71173","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! How do I determine the OU a user account belongs to?&#8212; CO Hey, CO. Ah, yes: the OU a user belongs to. No doubt a lot of you are thinking, \u201cWell, there\u2019s probably an OU property of some kind in Active Directory that gives you that information. All you have to do [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/71173","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=71173"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/71173\/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=71173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=71173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=71173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}