{"id":68803,"date":"2005-10-06T20:38:00","date_gmt":"2005-10-06T20:38:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/10\/06\/how-can-i-verify-that-none-of-my-local-user-accounts-have-a-blank-password\/"},"modified":"2005-10-06T20:38:00","modified_gmt":"2005-10-06T20:38:00","slug":"how-can-i-verify-that-none-of-my-local-user-accounts-have-a-blank-password","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-verify-that-none-of-my-local-user-accounts-have-a-blank-password\/","title":{"rendered":"How Can I Verify that None of My Local User Accounts have a Blank Password?"},"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! How can I verify that none of my local user accounts have a blank password?<BR><BR>&#8212; TB<\/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, TB. To begin with, we should point out that at least some of you won\u2019t need to make this check on computers within your domain; that\u2019s because you\u2019re using password policies in the domain that would prohibit the use of a blank password. (For example, you might require passwords to be at least 7 characters long, a policy that prevents anyone from using a blank password.) For organizations who don\u2019t have a password policy (or for workgroups or home computers), however, you can use a script like this to check for blank passwords:<\/P><PRE class=\"codeSample\">On Error Resume Next<\/p>\n<p>Set objNetwork = CreateObject(&#8220;Wscript.Network&#8221;)\nstrComputer = objNetwork.ComputerName<\/p>\n<p>strPassword = &#8220;&#8221;<\/p>\n<p>Set colAccounts = GetObject(&#8220;WinNT:\/\/&#8221; &amp; strComputer)\ncolAccounts.Filter = Array(&#8220;user&#8221;)<\/p>\n<p>For Each objUser In colAccounts\n    objUser.ChangePassword strPassword, strPassword\n    If Err = 0 or Err = -2147023569 Then\n        Wscript.Echo objUser.Name &amp; &#8221; is using a blank password.&#8221;\n    End If\n    Err.Clear\nNext\n<\/PRE>\n<P>Admittedly, some of you might be looking at this and thinking, \u201cThat\u2019s a nice little script and all. But how come you didn\u2019t just run some sort of query asking for a list of users who have a blank password?\u201d Well, there\u2019s a good reason for that: there\u2019s no way to run such a query. Even as administrators it\u2019s impossible for us to write a script that retrieves a user\u2019s password; there\u2019s no way to get that information. <\/P>\n<P>Therefore, we have to be a bit sneaky about this. What we do, instead, is try to change the user\u2019s password using the <B>ChangePassword<\/B> method. ChangePassword requires us to know the user\u2019s current password; in this script, we\u2019ll try using a blank password as the user\u2019s current password. If the script fails, that means the user is <I>not<\/I> using a blank password. If the script succeeds, however, that can only mean one thing: the user <I>is<\/I> using a blank password. In that case, we\u2019ll echo back the name of that user.<\/P>\n<P>To do this we start out by adding the <B>On Error Resume Next<\/B> statement, creating an instance of the <B>Wscript.Network<\/B> object, and then retrieving the value of the <B>ComputerName<\/B> property; fortuitously enough, ComputerName happens to be the name of the local computer. We set a variable named strPassword to an empty string (\u201c\u201d), then use this line of code to bind to the local computer:<\/P><PRE class=\"codeSample\">Set colAccounts = GetObject(&#8220;WinNT:\/\/&#8221; &amp; strComputer)\n<\/PRE>\n<P>Having made the connection, we next apply a <B>Filter<\/B> to ensure that we are working only with user accounts (we don\u2019t want to mess around with printers, services, groups, and other objects that are found in the local Security Accounts Manager):<\/P><PRE class=\"codeSample\">colAccounts.Filter = Array(&#8220;user&#8221;)\n<\/PRE>\n<P>Applying a filter leaves us with a collection consisting solely of local user accounts; in turn, we then set up a For Each loop to walk through that collection. For each account in the collection we call the ChangePassword method, passing the variable strPassword as both the first parameter (current password) and the second parameter (the new password):<\/P><PRE class=\"codeSample\">objUser.ChangePassword strPassword, strPassword\n<\/PRE>\n<P>We then immediately check the value of the <B>Err<\/B> object. If ChangePassword succeeds, then Err will be equal to 0; that means the user has a blank password. Alternatively, Err might be equal to -2147023569; that means the method <I>would<\/I> have succeeded except that, due to local policy, not enough time has elapsed since the last password change. But because the method would have succeeded, we know that the user has a blank password. If either condition is True we echo back the name of the user.<\/P>\n<TABLE id=\"EBE\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. Yes, technically we also change the password, although we\u2019re simply \u201cchanging\u201d it to a blank password, which is its current value. That means the user is still able to logon with a blank password. If we wanted to, we could make the second parameter passed to ChangePassword something other than an empty string. In that case, running the script would give the user a <I>new<\/I> password (whatever value we used as the second parameter).<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>We then clear the value of the error object (<B>Err.Clear<\/B>), loop around, and test the next account.<\/P>\n<P>And yes, you can easily modify this script to work against Active Directory accounts. Here\u2019s a sample script that tests all the accounts in the domain fabrikam.com:<\/P><PRE class=\"codeSample\">On Error Resume Next<\/p>\n<p>Const ADS_SCOPE_SUBTREE = 2<\/p>\n<p>strPassword = &#8220;&#8221;<\/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 AdsPath FROM &#8216;LDAP:\/\/dc=fabrikam,dc=com&#8217; WHERE objectCategory=&#8217;user'&#8221;  \nSet objRecordSet = objCommand.Execute<\/p>\n<p>objRecordSet.MoveFirst\nDo Until objRecordSet.EOF\n    strPath = objRecordSet.Fields(&#8220;AdsPath&#8221;).Value\n    Set strUser= GetObject(strPath)\n    strUser.ChangePassword strPassword, strPassword\n    If Err= 0 or Err = -2147023569 Then\n        Wscript.Echo strUser.CN\n    End If\n    Err.Clear\n    objRecordSet.MoveNext\nLoop\n<\/PRE>\n<P>If you use this script bear in mind that it tries to change the password for all your user accounts. If you have hundreds or thousands of accounts, the script could take an hour, maybe even more, to complete. There\u2019s nothing wrong with that, just something to be aware of. <\/P>\n<P>And, of course, you can also modify this script to test for other passwords. Want to see if anyone has a password of <I>password<\/I>? Then just set the value of strPassword accordingly:<\/P><PRE class=\"codeSample\">strPassword = &#8220;password&#8221;\n<\/PRE><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I verify that none of my local user accounts have a blank password?&#8212; TB Hey, TB. To begin with, we should point out that at least some of you won\u2019t need to make this check on computers within your domain; that\u2019s because you\u2019re using password policies in the domain that [&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,19,3,20,5,718],"class_list":["post-68803","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-activex-data-objects-ado","tag-scripting-guy","tag-user-accounts","tag-vbscript","tag-winnt"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I verify that none of my local user accounts have a blank password?&#8212; TB Hey, TB. To begin with, we should point out that at least some of you won\u2019t need to make this check on computers within your domain; that\u2019s because you\u2019re using password policies in the domain that [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68803","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=68803"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68803\/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=68803"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=68803"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=68803"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}