{"id":70043,"date":"2005-04-12T16:10:00","date_gmt":"2005-04-12T16:10:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/04\/12\/hey-scripting-guy-how-can-i-bind-to-a-user-account-using-something-other-than-the-cn-attribute\/"},"modified":"2005-04-12T16:10:00","modified_gmt":"2005-04-12T16:10:00","slug":"hey-scripting-guy-how-can-i-bind-to-a-user-account-using-something-other-than-the-cn-attribute","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-bind-to-a-user-account-using-something-other-than-the-cn-attribute\/","title":{"rendered":"Hey, Scripting Guy! How Can I Bind to a User Account Using Something Other Than the CN Attribute?"},"content":{"rendered":"<p><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Question\" border=\"0\" title=\"Hey, Scripting Guy! Question\" class=\"nearGraphic\" \/><\/p>\n<p>Hey, Scripting Guy! Can I bind to an Active Directory account using the user&rsquo;s mailNickname or their sAMAccoutName, something other than the CN?<\/p>\n<p>&#8212; MB<\/p>\n<p><img decoding=\"async\" height=\"5\" width=\"5\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" alt=\"Spacer\" border=\"0\" \/><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Answer\" border=\"0\" title=\"Hey, Scripting Guy! Answer\" class=\"nearGraphic\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><\/a><\/p>\n<p>Hey, MB. When you bind to an account in Active Directory, you need to pass GetObject the account&rsquo;s ADsPath. That means you need to use a line of code similar to this:<\/p>\n<pre class=\"codeSample\">Set objUser = GetObject(&ldquo;LDAP:\/\/cn=ken myer, ou=finance, dc=fabrikam, dc=com&rdquo;)<\/pre>\n<p>The ADsPath is actually composed of two pieces: the ADSI provider used to connect to Active Directory (<b>LDAP:\/\/<\/b>) and the distinguishedName attribute of the object you&rsquo;re trying to bind to (<b>cn=ken myer, ou=finance, dc=fabrikam, dc=com<\/b>). As you can see, the common name (CN) is the first element in the distinguish name. And &#8211; for better or worse &#8211; the common name <i>has<\/i> to be the first element in the distinguished name; if it&rsquo;s not, then it&rsquo;s not a distinguished name.<\/p>\n<p>For example, suppose you try binding to an account using the mailNickname instead:<\/p>\n<pre class=\"codeSample\">Set objUser = GetObject(&ldquo;LDAP:\/\/mailNickname=kenmyer, ou=finance, dc=fabrikam, dc=com&rdquo;)<\/pre>\n<p>That binding string is doomed to fail: to bind directly to an object in Active Directory you need to know the object&rsquo;s CN. (Actually there are some oddball exceptions; for example, you can bind to an object if you know the object&rsquo;s GUID. But it&rsquo;s probably safe to assume that you haven&rsquo;t memorized all the GUIDs for all your users.)<\/p>\n<p>But wait: don&rsquo;t leave just yet. As you probably know, we Scripting Guys love to build up dramatic tension: for reasons known only to ourselves, we delight in telling people that something can&rsquo;t be done, then turning right around and telling them how to do it anyway. And, to paraphrase Ronald Reagan, here we go again.<\/p>\n<p>Let&rsquo;s think about the situation for a moment. Why would you want to bind to an object using the mailNickname or the sAMAccountName? We&rsquo;re guessing there&rsquo;s one reason for that: you don&rsquo;t know the user&rsquo;s CN, but you <i>do<\/i> know their mailNickname or sAMAccountName. Well, why didn&rsquo;t you say so? If all we have is the mailNickname we can&rsquo;t directly bind to an Active Directory object. However, we <i>can<\/i> search Active Directory, find the user with that mailNickname, retrieve the user&rsquo;s distinguished name (which, of course, includes the CN), and <i>then<\/i> bind to the account. The net effect is the same: we supply nothing but the mailNickname and yet we end up binding to the user account. Sweet.<\/p>\n<p>Here&rsquo;s a script that searches Active Directory for the user with a mailNickname of <b>kenmyer<\/b>. After finding the account the script retrieves the distinguishedName attribute for the user and then binds to the account:<\/p>\n<pre class=\"codeSample\"><span style=\"background-color: #f0f0f0\">On Error Resume Next\n\nConst ADS_SCOPE_SUBTREE = 2\n\nSet objConnection = CreateObject(\"ADODB.Connection\")\nSet objCommand =   CreateObject(\"ADODB.Command\")\nobjConnection.Provider = \"ADsDSOObject\"\nobjConnection.Open \"Active Directory Provider\"\nSet objCommand.ActiveConnection = objConnection\n\nobjCommand.Properties(\"Page Size\") = 1000\nobjCommand.Properties(\"Searchscope\") = ADS_SCOPE_SUBTREE \n\nobjCommand.CommandText = _\n    \"SELECT distinguishedName FROM 'LDAP:\/\/dc=fabrikam,dc=com' WHERE objectCategory='user' \" &amp; _\n        \"AND mailNickname = 'kenmyer'\" \nSet objRecordSet = objCommand.Execute\n\nobjRecordSet.MoveFirst\nDo Until objRecordSet.EOF\n    strDN = objRecordSet.Fields(\"distinguishedName\").Value\n    objRecordSet.MoveNext\nLoop\n\nSet objUser = GetObject(\"LDAP:\/\/\" &amp; strDN)\nWscript.Echo objUser.Name<\/span>\n<\/pre>\n<p>We won&rsquo;t explain the intricacies of searching Active Directory; if you&rsquo;re looking for an explanation of what we&rsquo;re doing here &#8211; and why &#8211; take a look at this month&rsquo;s <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/tales\/sg0405.mspx\"><b>Tales from the Script<\/b><\/a> column. For now we&rsquo;ll just highlight a couple of key points.<\/p>\n<p>To begin with, here&rsquo;s the query that locates all the users with the mailNickname kenmyer (and because mailNicknames must be unique, there will be &#8211; at most &#8211; only one user that fits the criteria):<\/p>\n<p><span style=\"background-color: #f0f0f0\">objCommand.CommandText = _<br \/>&nbsp;&nbsp;&nbsp; &#8220;SELECT distinguishedName FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE objectCategory=&#8217;user&#8217; &#8221; &amp; _<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;AND mailNickname = &#8216;kenmyer&#8217;<\/span><\/p>\n<p>Pretty simple, huh? All we&rsquo;re doing here is returning the distinguishedName attribute for all the user accounts (<b>WHERE objCategory = &lsquo;user&rsquo;<\/b>) with the mailNickname <b>kenmyer<\/b>. When we execute this query we get back a recordset consisting of &#8211; at most &#8211; a single item. We then use this code to loop through the collection and store the user&rsquo;s distinguished name in a variable named strDN:<\/p>\n<pre class=\"codeSample\"><span style=\"background-color: #f0f0f0\">Do Until objRecordSet.EOF\n    strDN = objRecordSet.Fields(\"distinguishedName\").Value\n    objRecordSet.MoveNext\nLoop<\/span>\n<\/pre>\n<p>Now that we know the user&rsquo;s distinguished name we can bind to the user account and then do whatever we want (in our simple example, all we do is echo back the value of the <b>Name<\/b> attribute):<\/p>\n<pre class=\"codeSample\"><span style=\"background-color: #f0f0f0\">Set objUser = GetObject(\"LDAP:\/\/\" &amp; strDN)\nWscript.Echo objUser.Name<\/span>\n<\/pre>\n<p>Again, all we did was supply the mailNickname and yet we ended up binding to the user account. What if all we had was the sAMAccountName? In that case we&rsquo;d modify our query and look for a user with a specified sAMAccountName rather than a specified mailNickname:<\/p>\n<p><span style=\"background-color: #f0f0f0\">objCommand.CommandText = _<br \/>&nbsp;&nbsp;&nbsp; &#8220;SELECT distinguishedName FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE objectCategory=&#8217;user&#8217; &#8221; &amp; _<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;AND sAMAccountName = &#8216;kenmyer'&#8221;<\/span><\/p>\n<p>Hey, no need to thank us. After all, finding out ways to work around the system is what we do best!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! Can I bind to an Active Directory account using the user&rsquo;s mailNickname or their sAMAccoutName, something other than the CN? &#8212; MB Hey, MB. When you bind to an account in Active Directory, you need to pass GetObject the account&rsquo;s ADsPath. That means you need to use a line of code similar [&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,3,198,5],"class_list":["post-70043","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-scripting-guy","tag-users","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! Can I bind to an Active Directory account using the user&rsquo;s mailNickname or their sAMAccoutName, something other than the CN? &#8212; MB Hey, MB. When you bind to an account in Active Directory, you need to pass GetObject the account&rsquo;s ADsPath. That means you need to use a line of code similar [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70043","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=70043"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70043\/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=70043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=70043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=70043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}