{"id":70023,"date":"2005-04-14T16:53:00","date_gmt":"2005-04-14T16:53:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/04\/14\/how-can-i-display-a-multi-valued-attribute-returned-from-an-active-directory-search\/"},"modified":"2005-04-14T16:53:00","modified_gmt":"2005-04-14T16:53:00","slug":"how-can-i-display-a-multi-valued-attribute-returned-from-an-active-directory-search","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-display-a-multi-valued-attribute-returned-from-an-active-directory-search\/","title":{"rendered":"How Can I Display a Multi-Valued Attribute Returned from an Active Directory Search?"},"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 display a multi-valued attribute that I get back when using ADO to search Active Directory?<BR><BR>&#8212; ES<\/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, ES. For the most part Active Directory is a script writer\u2019s paradise; with very few exceptions anything you can do using the Active Directory snap-ins and GUI tools you can also do using a script. Of course, that doesn\u2019t mean there aren\u2019t a few bumps in the road. For example, dealing with dates and times in Active Directory can be a bit&#8230; challenging. After all, not only does Active Directory use some crazy date-time formats, but it also uses <I>different<\/I> date-time formats for different attributes. How\u2026nice\u2026.<\/P>\n<P>Another challenge crops up with multi-valued attributes. Most Active Directory properties are single-valued; in other words, the attribute can hold only one value. Names, for example, are single-valued: a user can have only one distinguished name, one SAM Account name, one first name, one last name, etc. Likewise, an account can have only one creation date and one last modified date; an account can be disabled or enabled but it can\u2019t be both. Single-valued attributes? Piece of cake.<\/P>\n<P>Multi-valued attributes are a different story. As the name implies, multi-valued attributes can contain more than one value. Take phone numbers, for example. As scary as this might be, it\u2019s not unusual for people to have more than one home phone number or more than one cell phone number. The designers of Active Directory could have chosen to ignore that reality and limit people to a single home phone number; alternatively, they could have created scores of additional attributes: homePhone1, homePhone2, homePhone3, homePhone4, etc. Neither of those approaches was particularly appealing. Therefore the decision was to create multi-valued attributes: a single property that could contain a whole bunch of values. There\u2019s a single-valued attribute that represents your primary home phone number, but there\u2019s also a multi-valued attribute that can hold as many additional home phone numbers as you might have (555-1111; 555-2222; 555-3333; etc.).<\/P>\n<P>That\u2019s actually a pretty good solution; the only problem is that you can\u2019t directly echo the value of a multi-valued attribute. Suppose you\u2019ve just conducted a search of Active Directory and returned the otherHomePhone attribute. If you try echoing the value using this line of code you\u2019re going to get a \u201cType mismatch\u201d error:<\/P><PRE class=\"codeSample\">Wscript.Echo objRecordSet.Fields(&#8220;otherHomePhone&#8221;).Value\n<\/PRE>\n<P>The problem is that a multi-valued attribute is actually an array of values; you can\u2019t echo <I>the<\/I> value because arrays don\u2019t have a single value. Instead, you need to create a For Each loop and echo each of the values found in the array of values:<\/P><PRE class=\"codeSample\">For Each strPhone in objRecordSet.Fields(&#8220;otherHomePhone&#8221;).Value\n    Wscript.Echo strPhone\nNext\n<\/PRE>\n<P>That\u2019s the secret right there: create a For Each loop and display each value in the array of values. This will work whether the user happens to have one additional home phone number, no additional home phone numbers, or scores of additional home phone numbers.<\/P>\n<P>See, not too bad. Here\u2019s a sample script that uses ADO to search Active Directory and echo back the <B>Name<\/B> and the <B>otherHomePhone<\/B> attribute values for each user in the domain. As you might have guessed, otherHomePhone happens to be a multi-valued attribute. But that\u2019s all right; we just use a For Each loop to loop through all the other home phone numbers for each user.<\/P>\n<P>Here\u2019s the script:<\/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 Name,otherHomePhone FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE objectCategory=&#8217;user'&#8221;  \nSet objRecordSet = objCommand.Execute<\/p>\n<p>objRecordSet.MoveFirst\nDo Until objRecordSet.EOF\n    Wscript.Echo objRecordSet.Fields(&#8220;Name&#8221;).Value\n    If Not IsNull(objRecordSet.Fields(&#8220;otherHomePhone&#8221;).Value) Then\n        For Each strPhone in objRecordSet.Fields(&#8220;otherHomePhone&#8221;).Value\n            Wscript.Echo &#8220;Home phone: &#8221; &amp; strPhone\n        Next\n    End If\n    objRecordSet.MoveNext\nLoop\n<\/PRE>\n<P>We did do one additional thing here: we checked to see if the otherHomePhone attribute was null (that is, we checked to see if the user actually <I>had<\/I> another home phone number). That\u2019s what we do with this line of code:<\/P><PRE class=\"codeSample\">If Not IsNull(objRecordSet.Fields(&#8220;otherHomePhone&#8221;).Value) Then\n<\/PRE>\n<P>Why did we do that? Well, suppose the user didn\u2019t have another home phone number. In that case our script would echo a line like this:<\/P><PRE class=\"codeSample\">Home phone:\n<\/PRE>\n<P>In our case we didn\u2019t want to clutter the output with lines like this. However, if you\u2019d prefer to see that a user <I>doesn\u2019t<\/I> have any additional home phone numbers then simply remove the If-Then statement. In other words:<\/P><PRE class=\"codeSample\">Do Until objRecordSet.EOF\n    Wscript.Echo objRecordSet.Fields(&#8220;Name&#8221;).Value\n    For Each strPhone in objRecordSet.Fields(&#8220;otherHomePhone&#8221;).Value\n        Wscript.Echo &#8220;Home phone: &#8221; &amp; strPhone\n    Next\n    objRecordSet.MoveNext\nLoop\n<\/PRE>\n<P>Incidentally, if you\u2019d like to know more about searching Active Directory (something we just plain ignored in today\u2019s column) check out this month\u2019s <A href=\"http:\/\/null\/technet\/scriptcenter\/resources\/tales\/sg0405.mspx\"><B>Tales from the Script<\/B><\/A>.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I display a multi-valued attribute that I get back when using ADO to search Active Directory?&#8212; ES Hey, ES. For the most part Active Directory is a script writer\u2019s paradise; with very few exceptions anything you can do using the Active Directory snap-ins and GUI tools you can also 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,3,8,5],"class_list":["post-70023","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-scripting-guy","tag-searching-active-directory","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I display a multi-valued attribute that I get back when using ADO to search Active Directory?&#8212; ES Hey, ES. For the most part Active Directory is a script writer\u2019s paradise; with very few exceptions anything you can do using the Active Directory snap-ins and GUI tools you can also do [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70023","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=70023"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70023\/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=70023"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=70023"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=70023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}