{"id":64553,"date":"2007-06-29T00:19:00","date_gmt":"2007-06-29T00:19:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/06\/29\/how-can-i-prompt-for-a-computer-name-and-then-delete-that-computer-account-from-active-directory\/"},"modified":"2007-06-29T00:19:00","modified_gmt":"2007-06-29T00:19:00","slug":"how-can-i-prompt-for-a-computer-name-and-then-delete-that-computer-account-from-active-directory","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-prompt-for-a-computer-name-and-then-delete-that-computer-account-from-active-directory\/","title":{"rendered":"How Can I Prompt for a Computer Name and Then Delete That Computer Account From Active Directory?"},"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 can I write a script that prompts the user for a computer name, then goes out and deletes that computer account from Active Directory?<BR><BR>&#8212; PH <\/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, PH. As a general rule, technical writers never experience writer\u2019s block. Why not? Well, writer\u2019s block usually comes about because you can\u2019t figure out how to get started; once you start writing you\u2019re usually fine. Technical writers never experience writer\u2019s block because technical writers never have any problem getting started. Are you writing about Active Directory? No problem; just start out by saying, \u201cActive Directory is a technology that \u2026.\u201d Writing about Terminal Services? Here\u2019s an opening sentence for you: \u201cTerminal Services is a technology that \u2026\u201d Writing about Group Policy? \u201cGroup Policy is a technology \u2013 \u201c well, you get the idea.<\/P>\n<P>For better or worse, however, the Scripting Guys aren\u2019t like other technical writers. Instead of starting every column off by saying, \u201cSystem administration scripting is a technology that \u2026,\u201d the Scripting Guys try to thrill and excite their readers by talking about fascinating subjects like <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/dec06\/hey1201.mspx\"><B>Turducken Bowls<\/B><\/A> and <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/begin\/ss0607.mspx\"><B>Scripting Dogs<\/B><\/A>. That\u2019s fine, except that, after awhile (this being, by unofficial count, the 718<SUP>th<\/SUP><I>Hey, Scripting Guy!<\/I> ever written), you run out of things to talk about.<\/P>\n<P>Unless, of course, you happen to drive the Scripting Car.<\/P>\n<P>OK, good point: at the moment nobody actually <I>drives<\/I> the Scripting Car; the Scripting Car just sits around like a big, dumb blob. (We\u2019ve long heard that pets resemble their owners, but we had no idea that <I>cars<\/I> resemble their owners.) <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/jun07\/hey0626.mspx\"><B>Two days ago<\/B><\/A> the Scripting Car was toast. <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/jun07\/hey0627.mspx\"><B>Yesterday<\/B><\/A> the Scripting Car was alive and well. Today \u2013 well, you can probably guess where we stand today.<\/P>\n<P>\u201cIt has to be a short somewhere,\u201d said the mechanic after the Scripting Car was towed to the shop for the second time this week. \u201cWe just can\u2019t figure out <I>where<\/I>. Let\u2019s just hope it\u2019s not in the injectors, though. You don\u2019t want it to be in the injectors.\u201d<\/P>\n<P>He\u2019s right: we definitely <I>don\u2019t<\/I> want it to be in the injectors.<\/P>\n<P>At the rate things are going, we\u2019re likely to have enough Scripting Car stories to keep us in business for a long time to come. But how do you transition from a story about a broken Scripting Car to a script that can locate and delete a computer account in Active Directory? As it turns out, you don\u2019t; you just show the script and call it good:<\/P><PRE class=\"codeSample\">Const ADS_SCOPE_SUBTREE = 2<\/p>\n<p>strComputer = InputBox(&#8220;Please enter the computer name:&#8221;, &#8220;Delete Computer Account&#8221;)<\/p>\n<p>If strComputer = &#8220;&#8221; Then\n    Wscript.Quit\nEnd If<\/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;<\/p>\n<p>Set objCommand.ActiveConnection = objConnection\nobjCommand.CommandText = &#8220;Select ADsPath From &#8221; &amp; _\n    &#8220;&#8216;LDAP:\/\/DC=fabrikam,DC=com&#8217; Where objectClass=&#8217;computer'&#8221; &amp; _\n        &#8221; and Name = &#8216;&#8221; &amp; strComputer &amp; &#8220;&#8216;&#8221;  \nobjCommand.Properties(&#8220;Page Size&#8221;) = 1000\nobjCommand.Properties(&#8220;Searchscope&#8221;) = ADS_SCOPE_SUBTREE \nSet objRecordSet = objCommand.Execute\nobjRecordSet.MoveFirst<\/p>\n<p>Do Until objRecordSet.EOF\n    Set objComputer = GetObject(objRecordSet.Fields(&#8220;ADsPath&#8221;).Value)\n    objComputer.DeleteObject (0)\n    objRecordSet.MoveNext\nLoop\n<\/PRE>\n<P>Barring any more shorts (particularly one in the injectors, which we don\u2019t want) we\u2019ll try to explain how this script works. As PH noted, he\u2019d like the script to prompt the user to enter the name of a computer. No problem; after defining a constant named ADS_SCOPE_SUBTREE we use this line of code to prompt the user to enter the name of a computer:<\/P><PRE class=\"codeSample\">strComputer = InputBox(&#8220;Please enter the computer name:&#8221;, &#8220;Delete Computer Account&#8221;)\n<\/PRE>\n<P>As you can see, there\u2019s nothing particularly fancy about that line of code. All we\u2019re doing is calling the <B>InputBox<\/B> function and asking it to display an input box on the screen. This particular input box features the message <I>Please enter the computer name:<\/I> and the caption <I>Delete Computer Account<\/I>. Assuming the user types in a name and then clicks <B>OK<\/B> the typed-in name will be stored in the variable strComputer. If the user clicks <B>Cancel<\/B> strComputer will be equal to an empty string (\u201c\u201d); in turn, that triggers this block of code, which causes the script to terminate:<\/P><PRE class=\"codeSample\">If strComputer = &#8220;&#8221; Then\n    Wscript.Quit\nEnd If\n<\/PRE>\n<P>Once we know the name of the computer account to be deleted our next step is to search Active Directory and locate the account in question. As usual, we won\u2019t discuss the ins and outs of Active Directory search scripts in any detail today; that\u2019s what our two-part <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/tales\/sg0405.mspx\"><B>Tales from the Script<\/B><\/A> series is for. However, we will take a quick peek at the SQL query used to search for this computer:<\/P><PRE class=\"codeSample\">objCommand.CommandText = &#8220;Select ADsPath From &#8221; &amp; _\n    &#8220;&#8216;LDAP:\/\/DC=fabrikam,DC=com&#8217; Where objectClass=&#8217;computer'&#8221; &amp; _\n        &#8221; and Name = &#8216;&#8221; &amp; strComputer &amp; &#8220;&#8216;&#8221;\n<\/PRE>\n<P>Again, this is pretty straightforward: all we\u2019re doing is searching the fabrikam.com domain for all items that have an <B>objectClass<\/B> equal to <I>computer<\/I> and a <B>Name<\/B> equal to the value of the variable strComputer. Because computer Names must be unique in a domain, this query lets us locate the very account that we want to delete.<\/P>\n<P>Because we\u2019re using a search script, any accounts that meet our criteria will be returned as part of a recordset; that\u2019s true even though there can be, at most, only one such account. Because of that, we need to set up a Do Until loop that runs until we\u2019ve looked at each and every item in the recordset. Or, as we high-tech types like to say, until the recordset\u2019s <B>EOF<\/B> (end-of-file) property is True:<\/P><PRE class=\"codeSample\">Do Until objRecordSet.EOF\n<\/PRE>\n<P>So what exactly do we <I>do<\/I> inside this loop? To begin with, we take the value of the item\u2019s <B>ADsPath<\/B> property and use it (and the <B>GetObject<\/B> method) to bind to the actual computer account in Active Directory:<\/P><PRE class=\"codeSample\">Set objComputer = GetObject(objRecordSet.Fields(&#8220;ADsPath&#8221;).Value)\n<\/PRE>\n<P>And yes, you\u2019re right: this works because the ADsPath attribute represents the computer\u2019s \u201caddress\u201d within Active Directory. For example:<\/P><PRE class=\"codeSample\">LDAP:\/\/CN=atl-fs-01, CN=Computers, dc=fabrikam, dc=COM\n<\/PRE>\n<P>After we make the connection we then call the <B>DeleteObject<\/B> method and delete the account:<\/P><PRE class=\"codeSample\">objComputer.DeleteObject (0)\n<\/PRE>\n<TABLE class=\"dataTable\" id=\"ERG\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. Why is the <B>(0)<\/B> parameter tacked on to the end of the DeleteObject method? Well, that\u2019s a required parameter even though, at the moment at least, 0 is the only allowed value. The parameter is still required, however, because additional values might be allowed \u201cin the future.\u201d If you ever find yourself musing, \u201cI wonder if the future has arrived yet,\u201d just check to see if DeleteObject accepts any values other than 0. If it does, then the future has arrived.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>One important thing to keep in mind here: the moment you call DeleteObject the computer account will be deleted. There\u2019s no prompting on the order of \u201cAre you sure you want to delete this account?\u201d, although you could easily add that code in yourself if you so desire.<\/P>\n<P><I>How<\/I> could you add in that code? Well, here\u2019s one way:<\/P><PRE class=\"codeSample\">intAnswer =&nbsp; Msgbox(&#8220;Are you sure you want to delete this computer?&#8221;, _\n    vbYesNo, &#8220;Delete Computer&#8221;)<\/p>\n<p>If intAnswer = vbYes Then\n&nbsp;&nbsp;&nbsp;objComputer.DeleteObject (0)\nEnd If\n<\/PRE>\n<P>After deleting the account we then call the <B>MoveNext<\/B> method to move to the next item in the recordset. Because there won\u2019t <I>be<\/I> a next item in the recordset that means the EOF property will be True and we\u2019ll automatically exit the Do Until loop.<\/P>\n<P>And that should do it, PH. We wish we had a snappier ending for today\u2019s column other than, \u201cAnd that should do it, PH.\u201d Unfortunately, we\u2019re having problems bringing things to a close lately. We seem to have no trouble with beginnings; endings are a different story. <\/P>\n<P>That said, let\u2019s just hope that this story doesn\u2019t end with, \u201cBad news, Scripting Guy who writes this column: this <I>is<\/I> in the injectors. That\u2019s something you don\u2019t want.\u201d No, we definitely <I>don\u2019t<\/I> want that.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I write a script that prompts the user for a computer name, then goes out and deletes that computer account from Active Directory?&#8212; PH Hey, PH. As a general rule, technical writers never experience writer\u2019s block. Why not? Well, writer\u2019s block usually comes about because you can\u2019t figure out how [&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,46,3,5],"class_list":["post-64553","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-computer-accounts","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I write a script that prompts the user for a computer name, then goes out and deletes that computer account from Active Directory?&#8212; PH Hey, PH. As a general rule, technical writers never experience writer\u2019s block. Why not? Well, writer\u2019s block usually comes about because you can\u2019t figure out how [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64553","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=64553"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64553\/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=64553"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=64553"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=64553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}