{"id":65933,"date":"2006-12-01T15:40:00","date_gmt":"2006-12-01T15:40:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/12\/01\/how-can-i-search-active-directory-for-user-names-stored-in-an-excel-spreadsheet\/"},"modified":"2006-12-01T15:40:00","modified_gmt":"2006-12-01T15:40:00","slug":"how-can-i-search-active-directory-for-user-names-stored-in-an-excel-spreadsheet","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-search-active-directory-for-user-names-stored-in-an-excel-spreadsheet\/","title":{"rendered":"How Can I Search Active Directory for User Names Stored in an Excel Spreadsheet?"},"content":{"rendered":"<p><img decoding=\"async\" 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\"><\/p>\n<p>Hey, Scripting Guy! How can I take user names from an Excel spreadsheet, search for those users in Active Directory, and then indicate whether or not each user was found?<\/p>\n<p>&#8212; SD<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><img decoding=\"async\" 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 decoding=\"async\" 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><\/p>\n<p>Hey, SD. You know, one of the drawbacks to writing a daily scripting column is that people never seem to believe you. For one thing, they don\u2019t believe that you write a daily scripting column. (Well, OK: many people believe that you write one, they just can\u2019t figure out <i>why<\/i> you write one.)<\/p>\n<p>For another, they aren\u2019t always convinced that you know what you\u2019re talking about, at least when it comes to <i>this<\/i> daily scripting column. After all, this column touches on everything from the exploits of <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/sept05\/hey0901.mspx\"><b>Home Run Baker<\/b><\/a> to <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/jul06\/hey0710.mspx\"><b>Schrodinger\u2019s cat<\/b><\/a> to the origin of <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/dec05\/hey1220.mspx\"><b>Grandparents Day<\/b><\/a>. That\u2019s all nice, but is any of it actually <i>true<\/i>?<\/p>\n<p>For example, there\u2019s little doubt that many people were skeptical when this column first broached the notion of the <b>turducken<\/b>: a chicken cooked inside a duck cooked inside a turkey. \u201cA chicken inside a duck inside a turkey?\u201d they sniffed. \u201cThen why not stuff the turkey inside a deer, the deer inside a bear, and the bear inside a hippopotamus?\u201d <\/p>\n<p>Hmmm \u2026. Are you thinking what we\u2019re thinking?<\/p>\n<p>As it turns out, though, this time the Scripting Guy who writes this column knew what he was talking about. Take a look at this email he received from Bannon O\u2019Leary:<\/p>\n<p>\u201cJust so ya&#8217;ll know the Turducken is a reality and purty darn good eatin\u2019. As a recent transplant to Nashville, TN from New Orleans I thought this was going to be my first Thanksgiving without a Turducken in a long time. Luckily a business trip took me back to New Orleans; a quick trip to the <a href=\"http:\/\/www.bestofneworleans.com\/dispatch\/2003-12-16\/ae_feat.html\" target=\"_blank\"><b>Gourmet Butcher Block<\/b><\/a> on the West Bank and I had secured a wonderful Thanksgiving meal.\u201d<\/p>\n<p>See: the Scripting Guy who writes this column was <i>right<\/i>! Now do you believe him when he says that the Scripting Editor <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/jun05\/hey0608.mspx\"><b>rides a broom<\/b><\/a> to work each day? <i>(Editor\u2019s Note: Given that the Scripting Guy who writes this column has also accused the Scripting Editor of <\/i><a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/aug06\/hey0830.mspx\"><b><i>being a Muggle<\/i><\/b><\/a><i>, he apparently can\u2019t be right <\/i>all<i> the time.)<\/i><\/p>\n<p>The moral of the story is that you really can trust <i>Hey, Scripting Guy!<\/i>, at least when it comes to esoteric trivia that no one else ever cares about. How about when it comes to answering scripting questions, especially questions like how someone can take user names from an Excel spreadsheet, search for those users in Active Directory, and then indicate whether or not each user was found? You\u2019ll have to judge that for yourself:<\/p>\n<pre class=\"codeSample\">Const ADS_SCOPE_SUBTREE = 2\nSet objConnection = CreateObject(\"ADODB.Connection\")\nSet objCommand = CreateObject(\"ADODB.Command\")\nobjConnection.Provider = \"ADsDSOObject\"\nobjConnection.Open \"Active Directory Provider\"\nSet objCommand.ActiveConnection = objConnection\nobjCommand.Properties(\"Page Size\") = 1000\nobjCommand.Properties(\"Searchscope\") = ADS_SCOPE_SUBTREE\nSet objExcel = CreateObject(\"Excel.Application\")\nSet objWorkbook = objExcel.Workbooks.Open(\"C:\\Scripts\\Test.xls\")\nobjExcel.Visible = True\ni = 1\nDo Until objExcel.Cells(i, 1).Value = \"\"\n    strName = objExcel.Cells(i,1)\n    objCommand.CommandText = _\n        \"SELECT * FROM 'LDAP:\/\/dc=fabrikam,dc=com' WHERE objectCategory='user' \" &amp; _\n            \"AND samAccountName='\" &amp; strName &amp; \"'\"\n    Set objRecordSet = objCommand.Execute\n    If objRecordset.RecordCount = 1 Then\n        objExcel.Cells(i,2) = \"Found\"\n    Else\n        objExcel.Cells(i,2) = \"Not found\"\n    End If\n    i = i + 1\n    objRecordset.Close\nLoop\nobjConnection.Close\n<\/pre>\n<p>You\u2019re right: this<b><\/b><i>is<\/i> a bit longer than the typical script discussed in this column. Is that going to be a problem for the Scripting Guys? Of course not; after all, we\u2019re just going to ignore a large portion of the script anyway. In particular, we won\u2019t discuss Active Directory searching in any detail; that\u2019s a subject way that\u2019s simply too complex for <i>Hey, Scripting Guy!<\/i> But don\u2019t despair: if you\u2019re not familiar with the ins and outs of writing scripts that can search Active Directory then just take a peek at our two-part series <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/tales\/sg0405.mspx\"><b>Dude, Where\u2019s My Printer?<\/b><\/a><\/p>\n<p>With that in mind we\u2019ll thus skip past the first eight lines of code and start here, with three lines in which we create an instance of the <b>Excel.Application<\/b> object, use the <b>Open<\/b> method to open to file C:\\Scripts\\Test.xls, and then set Excel\u2019s <b>Visible<\/b> property to True:<\/p>\n<pre class=\"codeSample\">Set objExcel = CreateObject(\"Excel.Application\")\nSet objWorkbook = objExcel.Workbooks.Open(\"C:\\Scripts\\Test.xls\")\nobjExcel.Visible = True\n<\/pre>\n<p>What does that do for us? That gives us a running instance of Test.xls that we can see on screen, an instance that \u2013 for our purposes \u2013 looks like this:<\/p>\n<p><img decoding=\"async\" height=\"275\" alt=\"Microsoft Excel\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/samexcel1.jpg\" width=\"329\" border=\"0\"><\/p>\n<p>As you can see, there\u2019s not much to our version of Test.xls. In column A we have a list of <b>samAccountNames<\/b>; in column B we have, well, nothing. But don\u2019t worry: before we\u2019re through we\u2019ll use column B to indicate whether or not these samAccountNames can be found in Active Directory.<\/p>\n<p>Once Excel is up and running our next task is to assign the value 1 to a variable named <i>i<\/i>, a counter variable that we\u2019ll use to keep track of our location within the spreadsheet. We then set up a Do Until loop that runs until we encounter an empty cell in column A:<\/p>\n<pre class=\"codeSample\">Do Until objExcel.Cells(i, 1).Value = \"\"\n<\/pre>\n<p>And yes, that\u2019s a good point: this script assumes that you didn\u2019t skip any rows when entering your user names. For example, suppose you have samAccountNames in rows 1 and 3, but for some reason have a blank cell in row 2. If you run this script it will only search for the name listed in row 1. Why? Because when it hits the blank cell in row 2 the script assumes that it\u2019s out of data and automatically exits the Do Until loop. <\/p>\n<p>Just something to watch out for: don\u2019t skip rows when entering your data.<\/p>\n<p>So what happens inside this Do Until loop? Well, for starters, we assign the <b>Value<\/b> of cell row 1, column 1 to a variable named strName (remember, <i>i<\/i> starts off equal to 1):<\/p>\n<pre class=\"codeSample\">strName = objExcel.Cells(i,1)\n<\/pre>\n<p>After we\u2019ve assigned this first samAccountName to strName we then construct a SQL query we can use to search fabrikam.com for all objects that: 1) have an <b>objectCategory<\/b> equal to <i>user<\/i>; and, 2) have a samAccountName equal to the value of strName:<\/p>\n<pre class=\"codeSample\">objCommand.CommandText = _\n    \"SELECT * FROM 'LDAP:\/\/dc=fabrikam,dc=com' WHERE objectCategory='user' \" &amp; _\n        \"AND samAccountName='\" &amp; strName &amp; \"'\"\n<\/pre>\n<p>We then use the <b>Execute<\/b> method to run the query and return a recordset consisting of all the users with a samAccountName equal to strName:<\/p>\n<pre class=\"codeSample\">Set objRecordSet = objCommand.Execute\n<\/pre>\n<p>As you probably know, samAccountNames must be unique within a domain. That means our recordset will either have 0 records (because it couldn\u2019t find a user account with that name) or 1 record (because the script <i>could<\/i> find a user with that name). In turn, that means we can verify whether or not a given name was found simply by checking the value of the recordset\u2019s <b>RecordCount<\/b> property (as the name implies, this tells us the number of records in the recordset):<\/p>\n<pre class=\"codeSample\">If objRecordset.RecordCount = 1 Then\n<\/pre>\n<p>If the RecordCount is equal to 1, we set the value of row 1, column 2 to <i>Found<\/i>; otherwise we set the value of row 1, column 2 to <i>Not found<\/i>. That\u2019s what we do here:<\/p>\n<pre class=\"codeSample\">If objRecordset.RecordCount = 1 Then\n    objExcel.Cells(i,2) = \"Found\"\nElse\n    objExcel.Cells(i,2) = \"Not found\"\nEnd If\n<\/pre>\n<p>We then increment the value of i by 1, meaning that, the second time through the loop, we\u2019ll check the value of row 2, column 1. After that we close the recordset and then loop around and repeat the process with the next row in the spreadsheet. When we\u2019re all done we close our connection to Active Directory and display the finished results:<\/p>\n<p><img decoding=\"async\" height=\"275\" alt=\"Microsoft Excel\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/samexcel2.jpg\" width=\"329\" border=\"0\"><\/p>\n<p>Not bad, if we do say so ourselves.<\/p>\n<p>OK, now that this scripting stuff is out of the way let\u2019s get back to something that people really care about: the turducken. According to Bannon, \u201cMy big issue is what to do with it, my wife is a vegetarian and my son is just working on getting his first tooth. 16 pounds of Turkey, Duck, and Chicken is gonna make for a lot of sandwiches.\u201d<\/p>\n<p>Yes, that <i>does<\/i> sound like a problem, doesn\u2019t it? Tell you what, Bannon: any time you have 16 pounds of Thanksgiving leftovers feel free to send them to the Scripting Guy who writes this column. <\/p>\n<p>Oh: and that goes for anyone else who might have Thanksgiving leftovers, too.<\/p>\n<p><br><\/p>\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\/dec06\/hey1201.mspx#top\"><img decoding=\"async\" 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\/dec06\/hey1201.mspx#top\">Top of page<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I take user names from an Excel spreadsheet, search for those users in Active Directory, and then indicate whether or not each user was found? &#8212; SD Hey, SD. You know, one of the drawbacks to writing a daily scripting column is that people never seem to believe you. For [&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,710,48,49,3,8,5],"class_list":["post-65933","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-excel-spreadsheet","tag-microsoft-excel","tag-office","tag-scripting-guy","tag-searching-active-directory","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I take user names from an Excel spreadsheet, search for those users in Active Directory, and then indicate whether or not each user was found? &#8212; SD Hey, SD. You know, one of the drawbacks to writing a daily scripting column is that people never seem to believe you. For [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/65933","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=65933"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/65933\/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=65933"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=65933"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=65933"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}