{"id":3409,"date":"2013-06-13T00:01:00","date_gmt":"2013-06-13T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/06\/13\/translate-active-directory-vbscript-into-powershellnot-me\/"},"modified":"2013-06-13T00:01:00","modified_gmt":"2013-06-13T00:01:00","slug":"translate-active-directory-vbscript-into-powershellnot-me","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/translate-active-directory-vbscript-into-powershellnot-me\/","title":{"rendered":"Translate Active Directory VBScript into PowerShell&#8212;Not Me!"},"content":{"rendered":"<p><strong style=\"font-size: 12px\">Summary<\/strong><span style=\"font-size: 12px\">: Don&rsquo;t translate old VBScript scripts that search Active Directory&mdash;instead use the Active Directory cmdlets from the RSAT.<\/span>\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\">&nbsp;Hey, Scripting Guy! I have this script that I use for auditing Active Directory. Basically, it queries to see what new user accounts have been created in the last month. I started translating it to Windows PowerShell (because I know that Windows PowerShell has the ability to create COM objects), but I fail to see the Windows PowerShell advantage. I mean, the script is as long as the original VBScript script. What gives?\n&mdash;BB\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\">&nbsp;Hello BB,\nMicrosoft Scripting Guy, Ed Wilson, is here. This morning I had to jump right into work, with little time even for a nice cup of tea. With the Atlanta TechStravaganza and TechEd Europe coming up back-to-back, there have been literally dozens of emails flying across the pond. The Scripting Guys will have a booth at TechEd Europe, and I will be conducting a couple of instructor-led labs about the cool new Windows PowerShell&nbsp;4.0 Desired State Configuration feature. This lab, which was completely full the last day of TechEd North America, is absolutely awesome.&nbsp;<span style=\"font-size: 12px\">Anyway, with temperatures in the mid-90s (Fahrenheit, 34 degrees Celsius), it is advisable to not get too terribly excited.<\/span><\/p>\n<h2>Good old COM-based ADO<\/h2>\n<p>In the VBScript days, it was not uncommon to use COM-based ADO to query Active Directory to find various pieces of information about users. In fact, this is a technique that I used all the way back in the Windows 2000 days (and the infamous <a href=\"http:\/\/en.wikipedia.org\/wiki\/Year_2000_problem\" target=\"_blank\">millennium bug<\/a>). Following is a 4.5 star script from the Script Center Repository: <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/0988ca91-133a-4203-9a64-b7b64d8f4344\" target=\"_blank\">Search for All Users by the Date Their Account was Created<\/a>.<\/p>\n<p style=\"padding-left: 30px\">On Error Resume Next<\/p>\n<p style=\"padding-left: 30px\">Const ADS_SCOPE_SUBTREE = 2<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">dtmCreationDate = &#8220;20071001000000.0Z&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Set objConnection = CreateObject(&#8220;ADODB.Connection&#8221;)<\/p>\n<p style=\"padding-left: 30px\">Set objCommand =&nbsp;&nbsp; CreateObject(&#8220;ADODB.Command&#8221;)<\/p>\n<p style=\"padding-left: 30px\">objConnection.Provider = &#8220;ADsDSOObject&#8221;<\/p>\n<p style=\"padding-left: 30px\">objConnection.Open &#8220;Active Directory Provider&#8221;<\/p>\n<p style=\"padding-left: 30px\">Set objCommand.ActiveConnection = objConnection<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">objCommand.Properties(&#8220;Page Size&#8221;) = 1000<\/p>\n<p style=\"padding-left: 30px\">objCommand.Properties(&#8220;Searchscope&#8221;) = ADS_SCOPE_SUBTREE<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">objCommand.CommandText = _<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; &#8220;SELECT Name FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE objectClass=&#8217;user&#8217; &#8221;&nbsp; &amp; _<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;AND whenCreated&gt;='&#8221; &amp; dtmCreationDate &amp; &#8220;&#8216;&#8221;<\/p>\n<p style=\"padding-left: 30px\">Set objRecordSet = objCommand.Execute<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">objRecordSet.MoveFirst<\/p>\n<p style=\"padding-left: 30px\">Do Until objRecordSet.EOF<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Wscript.Echo objRecordSet.Fields(&#8220;Name&#8221;).Value<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; objRecordSet.MoveNext<\/p>\n<p style=\"padding-left: 30px\">Loop\nHey, you know what, it is not too bad&mdash;only 26 lines long. It especially was not too bad if you had a great VBScript template with which to begin your work (you can find templates at <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/site\/search?f%5B0%5D.Type=RootCategory&amp;f%5B0%5D.Value=scripting&amp;f%5B0%5D.Text=Scripting%20Techniques&amp;f%5B1%5D.Type=SubCategory&amp;f%5B1%5D.Value=templates&amp;f%5B1%5D.Text=Scripting%20Templates&amp;f%5B2%5D.Type=ProgrammingLanguage&amp;f%5B2%5D.Value=VBS&amp;f%5B2%5D.Text=VB%20Script\" target=\"_blank\">Script Resources for IT Professionals<\/a>). If one were to translate this script into Windows PowerShell, using the same COM-based ADO, the script would be essentially the same, and it would be just as long. Luckily, we do not have to do that.<\/p>\n<h2>The Windows PowerShell&nbsp;way<\/h2>\n<p>In Windows PowerShell&nbsp;1.0, about the best one could do was to use the .NET Framework classes. This translated into using two classes. The resultant code is shown here:<\/p>\n<p style=\"padding-left: 30px\">$strFilter = &#8220;(&amp;(objectCategory=User)(whenChanged=20071001000000.0Z))&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$objDomain = New-Object System.DirectoryServices.DirectoryEntry<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$objSearcher = New-Object System.DirectoryServices.DirectorySearcher<\/p>\n<p style=\"padding-left: 30px\">$objSearcher.SearchRoot = $objDomain<\/p>\n<p style=\"padding-left: 30px\">$objSearcher.PageSize = 1000<\/p>\n<p style=\"padding-left: 30px\">$objSearcher.Filter = $strFilter<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$colProplist = &#8220;name&#8221;<\/p>\n<p style=\"padding-left: 30px\">foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$colResults = $objSearcher.FindAll()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">foreach ($objResult in $colResults)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; {$objItem = $objResult.Properties; $objItem.name}\nGroovy. This is only 17 lines of code, and we have the added bonus of avoiding the use of COM-based classes.\nIn Windows PowerShell&nbsp;2.0, the [adsisearcher] type accelerator is added, and that shortens the code by a few lines. But the greatest addition comes with the installation of the <a href=\"http:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=28972\" target=\"_blank\">Remote Server Administration Tools<\/a> (RSAT) because these introduce the Active Directory module. (For more information, see <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/01\/25\/hey-scripting-guy-january-25-2010.aspx\" target=\"_blank\">Hey, Scripting Guy! What&#8217;s Up with Active Directory Domain Services Cmdlets?<\/a>)<\/p>\n<h2>The Active Directory module and a one-liner<\/h2>\n<p>Upon installing the RSAT tools (for your specific version of client and server), you gain access to the <strong>Get-ADUser <\/strong>cmdlet. This makes finding information about newly created users the one-liner shown here:<\/p>\n<p style=\"padding-left: 30px\">Get-ADUser -Filter * -Properties whencreated | where whencreated -ge ((get-date).adddays(-30))\nBB, that is all there is to converting an Active Directory script to Windows PowerShell. Join me tomorrow when we are joined by Honorary Scripting Guy and Windows PowerShell MVP, Sean Kearney, for Part&nbsp;1 of his series,&nbsp;Create a New Virtual Machine with PowerShell.\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.\n<strong>Ed Wilson, Microsoft Scripting Guy<\/strong><span style=\"font-size: 12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Don&rsquo;t translate old VBScript scripts that search Active Directory&mdash;instead use the Active Directory cmdlets from the RSAT. &nbsp;Hey, Scripting Guy! I have this script that I use for auditing Active Directory. Basically, it queries to see what new user accounts have been created in the last month. I started translating it to Windows PowerShell [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,3,4,45],"class_list":["post-3409","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Don&rsquo;t translate old VBScript scripts that search Active Directory&mdash;instead use the Active Directory cmdlets from the RSAT. &nbsp;Hey, Scripting Guy! I have this script that I use for auditing Active Directory. Basically, it queries to see what new user accounts have been created in the last month. I started translating it to Windows PowerShell [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3409","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\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=3409"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3409\/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=3409"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=3409"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=3409"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}