{"id":63493,"date":"2007-11-30T00:55:00","date_gmt":"2007-11-30T00:55:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/11\/30\/hey-scripting-guy-how-can-i-remove-everything-from-an-active-directory-group-except-other-groups\/"},"modified":"2007-11-30T00:55:00","modified_gmt":"2007-11-30T00:55:00","slug":"hey-scripting-guy-how-can-i-remove-everything-from-an-active-directory-group-except-other-groups","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-remove-everything-from-an-active-directory-group-except-other-groups\/","title":{"rendered":"Hey, Scripting Guy! How Can I Remove Everything From an Active Directory Group Except Other Groups?"},"content":{"rendered":"<p><H2><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\"> <\/H2>\n<P>Hey, Scripting Guy! How can I remove all the members of a group unless that member is another group? I need a group that has only other groups as members, no individual users, computers, contacts, etc.<BR><BR>&#8212; TH<\/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, TH. You\u2019ll have to be patient with us this morning; after all, we\u2019re sending this column over the Internet and, well, you know how long <I>that<\/I> can take.<\/P>\n<P>What\u2019s that? Well, to be honest, we were also under the mistaken impression that things transmitted over the Internet arrive almost instantly. Yesterday, however, the Scripting Guy who writes this column had to arrange for the Scripting Son\u2019s SAT scores (which, while good, were nowhere near as good as his <I>Dad\u2019s<\/I> SAT scores) to be sent to the University of Idaho. After filling out the online form, he was given a choice of shipping options: Regular Shipping, or Over the Internet. What the heck, he thought. Let\u2019s send the scores over the Internet and get this wrapped up as quickly as possible.<\/P>\n<P>You\u2019d think that, by now, the Scripting Guy who writes this column would be used to being wrong. Nevertheless, he was still surprised by the estimated delivery time to send SAT scores over the Internet: 1 to 2 weeks. Of course, for $26.50 he could request Rush Shipping; in that case, the scores would be sent by courier within two business days. <\/P>\n<P>In other words, it\u2019s way faster to print out SAT scores, have a courier pick them up, have those scores flown across the country to Idaho, and then have another courier hand-deliver the scores to the University of Idaho than it is to simply send those scores electronically over the Internet.<\/P>\n<P>Hey, who said, \u201cThe SAT people must be using Microsoft software\u201d? Come on, be nice; as hard as it might be to remember, the Scripting Guys <I>do<\/I> work for Microsoft, you know.<\/P>\n<P>Speaking of which, we probably should actually do a little work for Microsoft rather than spend all day trying to send SAT scores over the Internet. In other words, we should probably see if we can figure out how to write a script that removes everyone except other groups from an Active Directory group. And, hopefully, take less than 1 to 2 weeks to figure it out.<\/P>\n<P>Never mind; turns out it only took 1 to 2<I> minutes<\/I> to figure that out:<\/P><PRE class=\"codeSample\">Set objGroup = GetObject _\n    (&#8220;LDAP:\/\/CN=Finance Department,OU=Finance,DC=fabrikam,DC=com&#8221;)<\/p>\n<p>For Each strUser in objGroup.Member\n    Set objMember = GetObject(&#8220;LDAP:\/\/&#8221; &amp; strUser)\n    If objMember.Class &lt;&gt; &#8220;group&#8221; Then\n        objGroup.Remove(objMember.ADsPath)\n    End If\nNext\n<\/PRE>\n<P>We hope you weren\u2019t expecting a really complicated script, TH; as you can see, this is actually a pretty simple little task to achieve. For example, to kick things off all we have to do is bind to the group in question; in this case, that\u2019s a group named Finance Department that\u2019s located in the Finance OU of fabrikam.com:<\/P><PRE class=\"codeSample\">Set objGroup = GetObject _\n    (&#8220;LDAP:\/\/CN=Finance Department,OU=Finance,DC=fabrikam,DC=com&#8221;)\n<\/PRE>\n<P>As you probably know, it\u2019s a simple enough matter to enumerate all the members of an Active Directory group; all you have to do is bind to the group (which we just did) and then loop through all the values stored in the <B>Member<\/B> attribute. And yes, that attribute really should be named <I>Members<\/I>, with an <I>s<\/I> on the end; after all, groups typically have more than one member. But for some reason, it\u2019s the Member attribute (no <I>s<\/I> on the end) instead. Go figure.<\/P>\n<P>Regardless, we can enumerate all the members of our group simply by setting up a For Each loop that looks like this:<\/P><PRE class=\"codeSample\">For Each strUser in objGroup.Member\n<\/PRE>\n<P>Now it gets just a little bit tricky. As we noted, all the members of a group are stored in the Member attribute; to be more specific, the distinguished name of each group member is stored in the Member attribute. In other words, the values stored in the Member attribute look something like this:<\/P><PRE class=\"codeSample\">CN=Ken Myer,OU=Finance,DC=fabrikam,DC=com \nCN=Jonathan Haas,OU=Finance,DC=fabrikam,DC=com\nCN=Pilar Ackerman,OU=Human Resources,DC=fabrikam,DC=com\n<\/PRE>\n<P>Is that a problem? Well, for us it is; needless to say, it can be pretty tough (especially for a script) to just look at a distinguished name and determine whether or not we\u2019re dealing with a user, a computer, a group, or whatever. That\u2019s why the first thing we do inside our For Each loop is this:<\/P><PRE class=\"codeSample\">Set objMember = GetObject(&#8220;LDAP:\/\/&#8221; &amp; strUser)\n<\/PRE>\n<P>What we\u2019re doing here is using the <B>GetObject<\/B> function and the user\u2019s distinguished name (which is stored in the variable strUser) to bind to the Active Directory account for the first member in the group. Why do we want to do that? Well, as it turns out, all Active Directory objects have a <B>Class<\/B> attribute that indicates the class the object belongs to: a user account has a Class attribute equal to <I>user<\/I>, a computer account has a Class attribute equal to <I>computer<\/I>, and so on. How do we know if a particular group member is (or isn\u2019t) another group? By using this line of code:<\/P><PRE class=\"codeSample\">If objMember.Class &lt;&gt; &#8220;group&#8221; Then\n<\/PRE>\n<P>Suppose the Class attribute <I>is<\/I> equal to <I>group<\/I>. Well, that\u2019s no big deal; in that case we simply zip back to the top of the loop and repeat this process with the next group member. <\/P>\n<P>Now, suppose that the Class attribute is <I>not<\/I> equal to <I>group<\/I> (that is, we\u2019re dealing with a user or computer or whatever). That can mean only one thing: this member needs to be removed from the group. (Remember, we\u2019re deleting everyone and everything that isn\u2019t another group.) Therefore, we simply grab the <B>ADsPath<\/B> property for this particular object and pass the value to the <B>Remove<\/B> method:<\/P><PRE class=\"codeSample\">objGroup.Remove(objMember.ADsPath)\n<\/PRE>\n<P>Just like that, the member will be removed from the group. And then we once again zip back around to the top of the loop and try this all over again with the next group member. When all is said and done, the only members left in our group will be other groups.<\/P>\n<P>Which is just exactly what we wanted to happen.<\/P>\n<P>By the way, we have a postscript to today\u2019s column. After entering his credit card number (yes, it costs money to have scores electronically sent over the Internet) the Scripting Guy hit the Submit button and asked that the scores be sent. At that point it wasn\u2019t clear what happened, if anything. The process <I>seemed<\/I> to work, but the University of Idaho did not appear in the list of schools that the Scripting Son\u2019s SAT scores had been sent to. The Scripting Guy who writes this column wasn\u2019t sure what to make of that; after all, if it takes up to 2 weeks to send scores over the Internet who knows how long it might take to update a Web page. <\/P>\n<P>Nevertheless, the Scripting Guy who writes this column decided to contact the help desk and ask about that. Once again he filled out the online form and clicked Submit. Here\u2019s the message he got back:<\/P>\n<TABLE id=\"EWF\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P>Thank you!<BR>Your information has been successfully submitted.<\/P>\n<P>Forms which have not been completed in their entirety cannot be processed. Please allow 2\u20144 weeks for requests to be processed.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>If we\u2019re reading that correctly, in a month or so he can expect to get a reply to his question. <\/P>\n<P>Isn\u2019t technology a wonderful thing? Imagine how long this process would take if we had to do what our ancestors did and pick up the phone and ask a real person a question?<\/P>\n<P>Oh, well. Tune in tomorrow \u2013 er, tune in next <I>summer<\/I> and we\u2019ll let you know how this all turned out.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I remove all the members of a group unless that member is another group? I need a group that has only other groups as members, no individual users, computers, contacts, etc.&#8212; TH Hey, TH. You\u2019ll have to be patient with us this morning; after all, we\u2019re sending this column over [&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,44,3,5],"class_list":["post-63493","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-groups","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I remove all the members of a group unless that member is another group? I need a group that has only other groups as members, no individual users, computers, contacts, etc.&#8212; TH Hey, TH. You\u2019ll have to be patient with us this morning; after all, we\u2019re sending this column over [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63493","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=63493"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63493\/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=63493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=63493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=63493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}