{"id":69823,"date":"2005-05-12T18:11:00","date_gmt":"2005-05-12T18:11:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/05\/12\/how-can-i-get-a-list-of-all-the-disabled-user-accounts-in-active-directory\/"},"modified":"2005-05-12T18:11:00","modified_gmt":"2005-05-12T18:11:00","slug":"how-can-i-get-a-list-of-all-the-disabled-user-accounts-in-active-directory","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-get-a-list-of-all-the-disabled-user-accounts-in-active-directory\/","title":{"rendered":"How Can I Get a List of All the Disabled User Accounts in 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 get a list of all the disabled user accounts in Active Directory?<BR><BR>&#8212; RT<\/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, RT. Now, just remember, you asked for this. We have a script that returns a list of disabled user accounts in Active Directory; the only problem is that part of the script is a little cryptic (to say the least), and we won\u2019t be able to fully explain how it all works in this column. But if you\u2019re fine with that then read on.<\/P>\n<P>Oh, what the heck: you might as well read on anyway. After all, you never can tell what you might find in one of these columns.<\/P>\n<P>The problem we have here is that account status (enabled or disabled) is part of the userAccountControl attribute. This happens to be an example of a bitmask attribute: a single attribute that actually houses numerous property values. In fact, all of the following property values are stored in this single attribute:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The user account is disabled.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The account is currently locked out.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>No password is required.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The user cannot change the password.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>This is a default account type that represents a typical user.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>When set, the password will not expire on this account.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>When set, this flag will force the user to log on using a smart card.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The user password has expired.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Bitmask attributes can be a bit confusing, but, for the most part, they aren\u2019t too hard to work with. The one exception occurs when you need to search Active Directory, which is exactly what we need to do here. Typically when you search Active Directory you use a SQL query similar to this:<\/P><PRE class=\"codeSample\">Select Name from &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; Where Department = &#8216;Finance&#8217;\n<\/PRE>\n<P>That works fine for most Active Directory attributes; it doesn\u2019t work so fine &#8211; in fact, it doesn\u2019t work at all &#8211; for bitmask attributes. Therefore we have to rely on Plan B, and use the LDAP query syntax instead:<\/P><PRE class=\"codeSample\">&lt;LDAP:\/\/dc=fabrikam,dc=com&gt;;(&amp;(objectCategory=User)&#8221; &amp; _\n        &#8220;(userAccountControl:1.2.840.113556.1.4.803:=2));Name;Subtree\n<\/PRE>\n<P>Yes, we know; we don\u2019t like it any better than you do. But, really, after you know what the individual parts represent this isn\u2019t as bad as it first looks:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>&lt;LDAP:\/\/dc=fabrikam,dc=com&gt;<\/B>. This is just simply the starting point for our search: the root of the fabrikam.com domain. Other than the angle brackets that surround the ADsPath this should be pretty familiar to you.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>(&amp;(objectCategory=User)<\/B>. This is part of our \u201cWhere\u201d clause (note that we don\u2019t actually use the word <I>Where<\/I> anywhere in the query). The <B>objectCategory=User<\/B> portion should be fairly straightforward; we\u2019re interested only in user objects. The <B>&amp;<\/B> is equivalent to the <B>AND<\/B> operator in a SQL clause: it just means we\u2019re combining objectCategory=User with something else.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>(userAccountControl:1.2.840.113556.1.4.803:=2))<\/B>. And this just happens to be that something else. It might look like gibberish, but this actually tells our script to search for objects (in this case, users) where bit <B>2<\/B> in the userAccountControl attribute has been enabled. We won\u2019t spend any time discussing bitmask attributes here; for a brief discussion see the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_usr_vrbt.mspx\" target=\"_blank\"><B>Reading User Account Password Attributes<\/B><\/A> section of the <I>Microsoft Windows 2000 Scripting Guide<\/I>. For now all we have to know is that if bit 2 is enabled then the user account is <I>disabled<\/I>.<\/P>\n<P>So what about the 1.2.840.1113556.1.4.803? That happens to be the LDAP bit matching rule and is equivalent to the <I>Boolean <\/I><B>AND<\/B> operator (we know, we know). In other words, this crazy-looking concoction is basically equal to this:<\/P><PRE class=\"codeSample\">If objUser.userAccountControl AND 2 Then\n<\/PRE>\n<P>If you\u2019re familiar with bitmasks this might make some sense to you. If not, well, don\u2019t worry too much about it. Go ahead and use the script as-is and save the understanding for later.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>Name<\/B>. This is the just attribute we want returned.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>Subtree<\/B>. This is our search scope; it simply means we want to search the entire Active Directory tree.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Clear as the proverbial mud, right? You might take a look at the April 2005 <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/tales\/sg0405.mspx\"><B>Tales from the Script<\/B><\/A> column, which offers an introduction to searching Active Directory. (And stay tuned for Part 2, due in May 2005). And if you\u2019re really interested in searching Active Directory (as you should be; it\u2019s a very powerful tool) you might take a look at this <A href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=25562\"><B>Scripting Guys webcast<\/B><\/A> as well.<\/P>\n<P>Oh, right: you might also want to take a look at the completed script that returns a list of all the disabled user accounts in Active Directory. Well, why didn\u2019t you say so?<\/P><PRE class=\"codeSample\">On Error Resume Next<\/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<\/p>\n<p>objCommand.CommandText = _\n    &#8220;&lt;LDAP:\/\/dc=fabrikam,dc=com&gt;;(&amp;(objectCategory=User)&#8221; &amp; _\n        &#8220;(userAccountControl:1.2.840.113556.1.4.803:=2));Name;Subtree&#8221;  \nSet objRecordSet = objCommand.Execute<\/p>\n<p>objRecordSet.MoveFirst\nDo Until objRecordSet.EOF\n    Wscript.Echo objRecordSet.Fields(&#8220;Name&#8221;).Value\n    objRecordSet.MoveNext\nLoop\n<\/PRE><BR>\n<DIV>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"0\" width=\"100%\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"\"><A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/may05\/hey0512.mspx#top\"><IMG height=\"9\" alt=\"Top of page\" src=\"http:\/\/www.microsoft.com\/technet\/mnplibrary\/templates\/MNP2.Common\/images\/arrow_px_up.gif\" width=\"7\" border=\"0\"><\/A><A class=\"topOfPage\" href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/may05\/hey0512.mspx#top\">Top of page<\/A><\/TD><\/TR><\/TBODY><\/TABLE><\/DIV><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I get a list of all the disabled user accounts in Active Directory?&#8212; RT Hey, RT. Now, just remember, you asked for this. We have a script that returns a list of disabled user accounts in Active Directory; the only problem is that part of the script is a little [&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,20,5],"class_list":["post-69823","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-scripting-guy","tag-searching-active-directory","tag-user-accounts","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I get a list of all the disabled user accounts in Active Directory?&#8212; RT Hey, RT. Now, just remember, you asked for this. We have a script that returns a list of disabled user accounts in Active Directory; the only problem is that part of the script is a little [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/69823","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=69823"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/69823\/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=69823"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=69823"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=69823"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}