{"id":54853,"date":"2008-11-20T11:25:00","date_gmt":"2008-11-20T11:25:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/11\/20\/hey-scripting-guy-how-can-i-find-locked-out-accounts\/"},"modified":"2008-11-20T11:25:00","modified_gmt":"2008-11-20T11:25:00","slug":"hey-scripting-guy-how-can-i-find-locked-out-accounts","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-find-locked-out-accounts\/","title":{"rendered":"Hey, Scripting Guy! How Can I Find Locked-Out Accounts?"},"content":{"rendered":"<h2><img decoding=\"async\" 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\" \/> <\/h2>\n<p>Hey, Scripting Guy! I know we probably should not do this, but we have account lockout set at work. If a user types in too many bad passwords, they are locked out forever. It requires a call to the help desk to have their account unlocked. The problem is that some users who are shall we say \u201cless motivated\u201d simply refuse to work. They say it is a network problem, and they do not call the help desk. If the boss says anything to them, they say the network is not working, and then he calls. We need a script that will list all the locked-out user accounts in our domain. Can this be done?<\/p>\n<p>&#8211; TB<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" 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\" \/> <\/p>\n<p>Hi TB,<\/p>\n<p>You know the danger of account lockout don\u2019t you? It makes for a very easy <a href=\"http:\/\/en.wikipedia.org\/wiki\/Denial-of-service_attack\">Denial of Service (DOS)<\/a> attack. Earlier this year we released the Windows 2008 Security Guide (available for <a href=\"http:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyID=fb8b981f-227c-4af6-a44b-b115696a80ac&amp;DisplayLang=en#filelist\">download<\/a> or <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/cc264463.aspx\">online browsing<\/a>). In it we recommend increasing the lockout threshold and setting moderate lockout duration. Then you monitor for suspicious activity. The idea is the lockout duration should be long enough to frustrate <a href=\"http:\/\/en.wikipedia.org\/wiki\/Script_kiddie\">script kitties<\/a>, but not network administrators. You should also read this <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/cc512613.aspx\">series of articles about passwords and pass phrases<\/a>. In the first two articles, Jesper Johansson talks about password strategies. In the last article, he talks about password policies which include, of course, account lockout policies. The articles make for interesting reading, and should frame an informed review of one\u2019s security policies. <\/p>\n<p>By the way, here is a picture of a script kitty I took while visiting the<a href=\"http:\/\/www.zoo.org\/\">Woodland Park Zoo<\/a> in Seattle, Washington, in the United States. We\u2019ll call him Get-Aslan:<\/p>\n<p><img decoding=\"async\" height=\"338\" alt=\"Image of script kitty\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/hey1120\/hsg_lockedout1.jpg\" width=\"450\" border=\"0\" \/> <\/p>\n<p>&nbsp;<\/p>\n<p>To search for locked-out user accounts, you need to first query Active Directory Directory Services (AD DS) for user accounts. Then go through the user accounts querying the <b>IsAccountLocked<\/b> property, and print out the <b>distinguishedName<\/b> attribute of the user. Here is <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/may05\/hey0512.mspx\">a VBScript script that accomplishes a similar task <\/a>. Here is the script written in Windows PowerShell (if you are unfamiliar with Windows PowerShell, you may want to check out our <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/winpsh\/manual\/default.mspx\">Windows PowerShell Owner\u2019s Manual<\/a>):<\/p>\n<pre class=\"codeSample\">$adsiSearcher = New-Object DirectoryServices.DirectorySearcher(\"LDAP:\/\/rootdse\")\n$adsiSearcher.filter = \"ObjectCategory=User\"\n$adsiSearcher.findAll() | \nForEach-Object `\n -Begin `\n  { \n   \"Locating locked out User accounts ...\" \n   $UserCount = 0\n  } `\n -Process `\n  {\n   If( ([adsi]$_.path).psbase.invokeGet(\"IsAccountLocked\") )\n     {\n      ([adsi]$_.path).DistinguishedName + \" is locked out\"\n       $UserCount ++\n     }\n  } `\n -End `\n  {\n   \"There were $userCount locked out User Accounts.\"\n  }\n<\/pre>\n<p>The script begins by creating an instance of the <b>DirectoryServices.DirectorySearcher<\/b> .NET Framework class. We use the <b>New-Object<\/b> cmdlet to create the <b>DirectorySearcher<\/b>. This allows us to search AD DS. Our constructor tells the <b>DirectorySearcher<\/b> we wish to search <b>rootdse<\/b> using the LDAP protocol. <\/p>\n<p>Keep in mind that LDAP must be in all caps. It is one of the few things that is case sensitive: <\/p>\n<pre class=\"codeSample\">$adsiSearcher = New-Object DirectoryServices.DirectorySearcher(\"LDAP:\/\/rootdse\")<\/pre>\n<p>Next we specify the filter to use with the <b>DirectorySearcher<\/b>. We use <b>ObjectCategory<\/b>, which is the name of an attribute in AD DS, and we filter out if the <b>ObjectCategory<\/b> has a value of <b>user<\/b>. This is seen here: <\/p>\n<pre class=\"codeSample\">$adsiSearcher.filter = \"ObjectCategory=User\"<\/pre>\n<p>We use the <b>findall<\/b> method to return all the user objects, and then we pipeline the user objects to the <b>Foreach-Object<\/b> cmdlet. This is seen here: <\/p>\n<pre class=\"codeSample\">$adsiSearcher.findAll() |<\/pre>\n<p>The <b>ForEach-Object<\/b> allows us to work through all the user objects as they come across the pipeline. We use the backtick to continue the command to the next line: <\/p>\n<pre class=\"codeSample\">ForEach-Object `<\/pre>\n<p>We begin by specifying an action for the <b>-begin<\/b> parameter. This code will be executed once within the entire <b>ForEach-Object<\/b> cmdlet. We print out a message that says \u201cLocating locked out User accounts,\u201d and we initialize the <b>$userCount<\/b> variable to <b>0<\/b>. This is seen&nbsp;here: <\/p>\n<pre class=\"codeSample\">-Begin `\n{ \n   \"Locating locked out User accounts ...\" \n   $UserCount = 0\n  } `\n<\/pre>\n<p>The <b>process<\/b> parameter is used to perform an action on each object that comes across the pipeline. We use the <b>[adsi]<\/b> type accelerator and give it the path of the <b>SearchResult<\/b> object. This gives us a <b>DirectoryEntry<\/b> object. We use the <b>psbase<\/b> property to gain access to the <b>invokeGet<\/b> method, which retrieves the <b>IsAccountLocked<\/b> property. If this value is true, we&nbsp;:<\/p>\n<pre class=\"codeSample\">-Process `\n  {\n   If( ([adsi]$_.path).psbase.invokeGet(\"IsAccountLocked\") )\n     {\n      ([adsi]$_.path).DistinguishedName + \" is locked out\"\n       $UserCount ++\n     }\n  } `\n<\/pre>\n<p>The ending of our script prints out the count of the number of locked-out accounts. This is seen&nbsp;here:<\/p>\n<pre class=\"codeSample\">-End `\n  {\n   \"There were $userCount locked out User Accounts.\"\n  }\n<\/pre>\n<p>That\u2019s it. See you tomorrow for Quick-Hits Friday. Peace! Oh, by the way, if you are in Seattle, Washington, stop by and say hi to the script kitty. Here\u2019s <a href=\"http:\/\/www.zoo.org\/\">all the information you need<\/a>.<\/p>\n<p><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><span class=\"Apple-style-span\"><b><b>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/b><\/b><\/span><\/font><\/p>\n<p><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><b><\/b><\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I know we probably should not do this, but we have account lockout set at work. If a user types in too many bad passwords, they are locked out forever. It requires a call to the help desk to have their account unlocked. The problem is that some users who are shall [&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,45],"class_list":["post-54853","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-windows-powershell"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I know we probably should not do this, but we have account lockout set at work. If a user types in too many bad passwords, they are locked out forever. It requires a call to the help desk to have their account unlocked. The problem is that some users who are shall [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54853","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=54853"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54853\/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=54853"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=54853"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=54853"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}