{"id":70863,"date":"2004-12-07T10:25:00","date_gmt":"2004-12-07T10:25:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2004\/12\/07\/how-can-i-return-a-list-of-all-my-computers-except-those-in-a-specified-ou\/"},"modified":"2004-12-07T10:25:00","modified_gmt":"2004-12-07T10:25:00","slug":"how-can-i-return-a-list-of-all-my-computers-except-those-in-a-specified-ou","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-return-a-list-of-all-my-computers-except-those-in-a-specified-ou\/","title":{"rendered":"How Can I Return a List of All My Computers Except Those in a Specified OU?"},"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! I need to get back a list of all the computers in my domain, <I>except<\/I> for the computers which are in our Test Lab OU. How do I do that?<BR><BR>&#8212; AM<\/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, AM. This seems to be one of the hot new trends in the IT world: in the past two weeks we\u2019ve gotten three similar emails, all involving administrators who want to exclude a particular OU when listing all the computers in their domain. In this case, it appears you\u2019re not interested in computers housed in your test lab; in the other two cases, we had an admin who wanted to exclude developer machines, and an admin who didn\u2019t want domain controllers showing up in the list. Regardless, the basic idea is the same: you want a list of all your computers except for those one specific OU.<\/P>\n<P>If you\u2019re an avid reader of <I>Hey, Scripting Guy!<\/I> (and who isn\u2019t?) then you know that 9 times out of 10 our answer to a question is, \u201cSearch Active Directory.\u201d That\u2019s going to be our answer today as well, although we must confess that we\u2019re not 100% satisfied with that answer (you\u2019ll see why in a moment). At first glance, you might think this would be an easy search to carry out in Active Directory; after all, you\u2019d have to do nothing more than include a WHERE clause that tells the script to skip any computers found in the Test Lab OU. In other words:<\/P><PRE class=\"codeSample\">objCommand.CommandText = _\n    &#8220;SELECT Name FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE OU &lt;&gt; &#8216;TestLab OU&#8217; AND &#8221; _\n        &amp; &#8220;objectCategory=&#8217;computer'&#8221;\n<\/PRE>\n<P>This is a great solution, except for one problem: Active Directory computer accounts don\u2019t have a property named OU; that means you can\u2019t use the OU in a WHERE clause. So much for Plan A.<\/P>\n<P>Of course, you might then think, \u201cHey, what about the Distinguished Name (DN)?\u201d After all, the DN for a computer (e.g., <B>CN=atl-ws-01,OU=Test Lab OU,DC=fabrikam,DC=com<\/B>) contains the name of the OU where the computer account resides. Couldn\u2019t we just do a wildcard search on the Distinguished Name, something similar to this:<\/P><PRE class=\"codeSample\">objCommand.CommandText = _\n    &#8220;SELECT Name FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE distinguishedName &lt;&gt; &#8221;  _\n        &#8221; &#8216;*OU=Finance&#8217; AND objectCategory=&#8217;computer'&#8221;\n<\/PRE>\n<P>Alas, this won\u2019t work, either. As it turns out, the DN is a \u201cconstructed\u201d attribute. The DN isn\u2019t actually stored in Active Directory, it\u2019s constructed on-the-fly any time you request it. Thus you can\u2019t do a wildcard search on the distinguishedName attribute. And don\u2019t bother asking about the ADsPath attribute, which also contains the OU name; you can\u2019t do a wildcard search on the ADsPath, either.<\/P>\n<P>In fact, as far as we know, the only way to do this is to conduct a search that returns a list of <I>all<\/I> your computers. When you get that list back, you\u2019re probably going to do something with it (for now, we\u2019ll assume you just want to echo the computer names to the screen). Before anything is done to a computer in the list, however, our script will check the DN to see if the target string (for example, <B>OU=Test Lab OU<\/B>) can be found. If it is, the script will simple skip that computer and go on to the machine in the list. If the target string isn\u2019t found, then the script will echo the computer name.<\/P>\n<P>Maybe this will make more sense if you see the actual 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, distinguishedName FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; &#8221; _\n        &amp; &#8220;WHERE objectCategory=&#8217;computer'&#8221;  \nSet objRecordSet = objCommand.Execute<\/p>\n<p>objRecordSet.MoveFirst\nDo Until objRecordSet.EOF\n    intTestOU = InStr(objRecordSet.Fields(&#8220;distinguishedName&#8221;).Value, &#8220;OU=Test Lab OU&#8221;)\n    If intTestOU = 0 Then\n        Wscript.Echo objRecordSet.Fields(&#8220;Name&#8221;).Value\n    End If\n    objRecordSet.MoveNext\nLoop\n<\/PRE>\n<P>The lines of code we care about are these:<\/P><PRE class=\"codeSample\">intTestOU = InStr(objRecordSet.Fields(&#8220;distinguishedName&#8221;).Value, &#8220;OU=Test Lab OU&#8221;)\nIf intTestOU = 0 Then\n    Wscript.Echo objRecordSet.Fields(&#8220;Name&#8221;).Value\nEnd If\n<\/PRE>\n<P>What we\u2019re doing here is using the InStr function to see if the string <B>OU=TestLab OU<\/B> can be found anywhere within the computer\u2019s Distinguished Name. If the string is found, then intTestOU gets set to the character position where the string begins. For example, in the DN <B>CN=atl-ws-01,OU=Test Lab OU,DC=fabrikam,DC=com<\/B>, intTestOu would be set to 14, because our target phrase begins at the 14<SUP>th<\/SUP> letter in the string.<\/P>\n<P>But what if intTestOU equals zero? That can only mean one thing: the target phrase wasn\u2019t found. In turn, that must mean this particular computer is <I>not<\/I> in the Test Lab OU, so we go ahead and echo the computer name. Thus we end up echoing the names of all the computers <I>except<\/I> those in the Test Lab OU. <\/P>\n<P>Like we said, this approach does the job, although it lacks a certain elegance. But, hey, style isn\u2019t everything, right? <\/P>\n<P>Alternatively, you might consider storing OU names in an unused computer account attribute; for example, you could record the OU name in the description attribute. That way, you <I>could<\/I> search on that attribute, using a query similar to this:<\/P><PRE class=\"codeSample\">objCommand.CommandText = _\n    &#8220;SELECT Name FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE objectCategory=&#8217;computer&#8217; &#8221; &amp; _\n        &#8220;AND description&lt;&gt;&#8217;Test Lab OU'&#8221;\n<\/PRE>\n<P>This works great; you\u2019ll just have to remember to change the value of the description attribute should you ever move the computer to a new OU<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I need to get back a list of all the computers in my domain, except for the computers which are in our Test Lab OU. How do I do that?&#8212; AM Hey, AM. This seems to be one of the hot new trends in the IT world: in the past two weeks [&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-70863","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! I need to get back a list of all the computers in my domain, except for the computers which are in our Test Lab OU. How do I do that?&#8212; AM Hey, AM. This seems to be one of the hot new trends in the IT world: in the past two weeks [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70863","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=70863"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70863\/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=70863"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=70863"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=70863"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}