{"id":65873,"date":"2006-12-11T15:45:00","date_gmt":"2006-12-11T15:45:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/12\/11\/how-can-i-copy-my-users-phone-number-attribute-to-their-description-attribute\/"},"modified":"2006-12-11T15:45:00","modified_gmt":"2006-12-11T15:45:00","slug":"how-can-i-copy-my-users-phone-number-attribute-to-their-description-attribute","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-copy-my-users-phone-number-attribute-to-their-description-attribute\/","title":{"rendered":"How Can I Copy My Users&#8217; Phone Number Attribute to Their Description Attribute?"},"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 copy a user\u2019s phone number to his or her description for all the users in Active Directory?<\/p>\n<p>&#8212; DL<\/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, DL. You know, the Scripting Guy who writes this column considers today\u2019s column to be his all-time favorite. Why? Because while you\u2019re at work reading this he hasn\u2019t even gotten out of bed yet. (Or, if he has, he\u2019s just lying around the house eating doughnuts and watching TV.) Talk about the sweet life, huh?<\/p>\n<p>Ah, yes, that\u2019s a good question: how can he write and publish a column if he\u2019s sleeping in past 10:00 AM? What is he, a master of the dark arts or something?<\/p>\n<p>No, of course not. He\u2019s simply \u2013 um, wait a second, we mean yes, yes he <i>is<\/i> a master of the dark arts, an evil sorcerer who will place a terrible spell on you unless you send him $19.95. No checks; credit cards or money orders only. Operators are standing by.<\/p>\n<p>What\u2019s that? You say you\u2019re a <i>little<\/i> scared, but you\u2019d like to see a demonstration of his powers before sending in the money? Well, we can do that, but, just remember, you asked for it. Hold on a second while we summon the Demons of the Netherworld (thanks goodness for instant messaging, huh?). <\/p>\n<p>OK, here we go. By the power of Grayskull, we command thee to copy the telephone number attribute to the description, and for each and every user in a domain:<\/p>\n<pre class=\"codeSample\">On Error Resume Next\nConst 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\nobjCommand.CommandText = \"SELECT AdsPath FROM 'LDAP:\/\/dc=fabrikam,dc=com' WHERE objectCategory='user'\"\nSet objRecordSet = objCommand.Execute\nobjRecordSet.MoveFirst\nDo Until objRecordSet.EOF\n    strUserPath = objRecordSet.Fields(\"AdsPath\").Value\n    Set objUser = GetObject(strUserPath)\n    strTelephone = objUser.telephoneNumber\n    objUser.Description = strTelephone\n    objUser.SetInfo\n    objRecordSet.MoveNext\nLoop\n<\/pre>\n<p>Sorry about that. The smoke will clear up in a second but the smell of brimstone might linger for a little while.<\/p>\n<p>OK. As it turns out, we don\u2019t really have time to discuss this script in minute detail, at least not the part that explains how to search Active Directory; after all, <i>Oprah<\/i> will be on any minute now. But don\u2019t despair; if you need to know the fundamentals of conducting an Active Directory search take a look 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> available now for the low introductory price of just $19.95. Operators are standing by.<\/p>\n<p>Come to think of it, that two-part series might actually be available for no charge. But you might want to send in the money anyway, just to be on the safe side.<\/p>\n<p>About all we <i>will<\/i> do today is point out that this is the query used to select the value of the <b>ADsPath<\/b> attribute for all the users (<b>objectCategory=\u2019user\u2019<\/b>) in the fabrikam.com domain:<\/p>\n<pre class=\"codeSample\">objCommand.CommandText = \"SELECT AdsPath FROM 'LDAP:\/\/dc=fabrikam,dc=com' WHERE objectCategory='user'\"\n<\/pre>\n<p>Why the ADsPath attribute? Well, ADsPath returns a connection string that makes it easy to bind to a user account in Active Directory. For example:<\/p>\n<pre class=\"codeSample\">LDAP:\/\/cn=Ken Myer,ou=Finance,dc=fabrikam,dc=com\n<\/pre>\n<p>That\u2019s important, because when we search Active Directory our queries are read-only; we can\u2019t write some sort of Update query that automatically copies a user\u2019s telephone number to his or her description attribute. Instead, we have to bind to each individual user account and copy the telephone number to the description. (We know, that sounds slow and tedious. But the script does all the work and, unless you have several million user accounts, it all happens remarkably fast as well.)<\/p>\n<p>When we call the <b>Execute<\/b> method and run our query we get back a recordset containing the ADsPath for each user in the domain. We then set up a Do Until loop that runs until the value of the recordset\u2019s <b>EOF<\/b> (End-Of-File) property is true; in other words, until we\u2019ve looped through all the records in the recordset:<\/p>\n<pre class=\"codeSample\">Do Until objRecordSet.EOF\n<\/pre>\n<p>The first thing we do inside the loop is grab the value of the ADsPath attribute and store it in a variable named strUserPath; we then use that variable to connect to the actual account object for that user. That\u2019s what these two lines of code are for:<\/p>\n<pre class=\"codeSample\">strUserPath = objRecordSet.Fields(\"AdsPath\").Value\nSet objUser = GetObject(strUserPath)\n<\/pre>\n<p>After we make the connection we take the value of the <b>telephoneNumber<\/b> attribute and store it in a variable named strTelephone. We then use these two lines of code to set the user\u2019s <b>Description<\/b> attribute to his or her telephone number:<\/p>\n<pre class=\"codeSample\">objUser.Description = strTelephone\nobjUser.SetInfo\n<\/pre>\n<p>Whatever you do, don\u2019t leave out the call to the <b>SetInfo<\/b> method; that\u2019s the method that actually writes the changes back to Active Directory. If you don\u2019t call SetInfo the change will be made in memory, but <i>not<\/i> in Active Directory.<\/p>\n<p>After that we call the <b>MoveNext<\/b> method to move to the next record in the recordset and then repeat the process for the next user.<\/p>\n<p>And yes, we could have combined a couple of these lines of code in order to make the script a tiny bit smaller. However, we thought this method would be a little easier for people to follow.<\/p>\n<p>Seeing as how Microsoft\u2019s lawyers are breathing down our necks we should probably come clean here and state, for the record, that the Scripting Guy who writes this column is not an evil sorcerer and has no magic powers. (He used to be able to juggle a little, but that probably doesn\u2019t count.) Instead, the Scripting Guy who writes this column is actually on vacation until the first of the year; however, he wrote a few extra columns before he left, the better to get everyone through this week and tide you over until he gets back. What a wonderful and selfless act, huh?<\/p>\n<table class=\"dataTable\" id=\"EHF\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p><b>Note<\/b>. OK, he didn\u2019t really do it to be nice; he only wrote these columns because the Scripting Editor said he should. And we always do whatever the Scripting Editor says, because, like all editors everywhere, she really <i>is<\/i> a practitioner of the dark arts. What, you thought Peter Costantini was <i>born<\/i> a newt?<\/p>\n<p>But take heart, Peter: she can\u2019t hold a grudge forever.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I copy a user\u2019s phone number to his or her description for all the users in Active Directory? &#8212; DL Hey, DL. You know, the Scripting Guy who writes this column considers today\u2019s column to be his all-time favorite. Why? Because while you\u2019re at work reading this he hasn\u2019t even [&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,20,5],"class_list":["post-65873","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-scripting-guy","tag-user-accounts","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I copy a user\u2019s phone number to his or her description for all the users in Active Directory? &#8212; DL Hey, DL. You know, the Scripting Guy who writes this column considers today\u2019s column to be his all-time favorite. Why? Because while you\u2019re at work reading this he hasn\u2019t even [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/65873","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=65873"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/65873\/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=65873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=65873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=65873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}