{"id":70893,"date":"2004-12-02T14:54:00","date_gmt":"2004-12-02T14:54:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2004\/12\/02\/how-can-i-prevent-a-local-user-from-changing-his-or-her-password\/"},"modified":"2004-12-02T14:54:00","modified_gmt":"2004-12-02T14:54:00","slug":"how-can-i-prevent-a-local-user-from-changing-his-or-her-password","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-prevent-a-local-user-from-changing-his-or-her-password\/","title":{"rendered":"How Can I Prevent a Local User From Changing His or Her 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 configure a local user account so that the user can\u2019t change his or her password?<BR><BR>&#8212; DC<\/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, DC. The secret here lies in the mysterious userFlags attribute. We\u2019ll show you how to set a user account so that the user can\u2019t change his or her password, then we\u2019ll fill you in on some of the other local user account properties that can be managed with the userFlags attribute. And by then it will hopefully be time for lunch!<\/P>\n<P>First the script that prevents a user from changing his or her password:<\/P><PRE class=\"codeSample\">Const ADS_UF_PASSWD_CANT_CHANGE = &amp;H0040<\/p>\n<p>Set objUser = GetObject(&#8220;WinNT:\/\/atl-ws-01\/kenmyer&#8221;)<\/p>\n<p>If Not objUser.UserFlags AND ADS_UF_PASSWD_CANT_CHANGE Then\n    objPasswordNoChangeFlag = objUser.UserFlags XOR ADS_UF_PASSWD_CANT_CHANGE\n    objUser.Put &#8220;userFlags&#8221;, objPasswordNoChangeFlag \n    objUser.SetInfo\nEnd If\n<\/PRE>\n<P>We start out by defining a constant (with the catchy name ADS_UF_PASSWD_CANT_CHANGE) that we\u2019ll need to identify the proper \u201cswitch\u201d inside the userFlags attribute. The userFlags attribute is an example of a bitmask attribute, a single attribute that contains multiple properties and property values. For now, just consider a bitmask as being a bank of switches, with each switch representing a different property. If the switch for <B>User Can\u2019t Change Password<\/B> is on, then the user can\u2019t change his or her password; if the switch is off, then the user <I>can<\/I> change their password. That part is fairly intuitive; the only hard part of dealing with a bitmask is that the \u201cswitches\u201d don\u2019t have names like User Can\u2019t Change Password. Instead, they have hexadecimal values, like &amp;H0040. To carry out our task, we need to flip the <B>&amp;H0040<\/B> switch. That\u2019s why we define this constant.<\/P>\n<P>Next we connect to the kenmyer account on the computer atl-ws-01. At that point, we check to see if the switch in question is already on. When working with bitmasks, you\u2019ll often see code like this:<\/P><PRE class=\"codeSample\">If objUser.UserFlags AND ADS_UF_PASSWD_CANT_CHANGE Then\n<\/PRE>\n<P>In plain English, this can be read as \u201cIf the userFlags attribute is present and if the ADS_UF_PASSWD_CANT_CHANGE switch is on, then this statement is true and we should do something.\u201d In our case, we\u2019re not interested in switches that are on; if the can\u2019t change password flag is already set, then our work is done. We\u2019re only interested in switches that are off. Hence we use this line of code, which takes action only if the switch is <I>not<\/I> on:<\/P><PRE class=\"codeSample\">If Not objUser.UserFlags AND ADS_UF_PASSWD_CANT_CHANGE Then\n<\/PRE>\n<P>Now we\u2019re <I>really<\/I> going to confuse you. Take a look at this line of code:<\/P>\n<P>objPasswordNoChangeFlag = objUser.UserFlags XOR ADS_UF_PASSWD_CANT_CHANGE<\/P>\n<P>Actually &#8211; all appearances aside &#8211; this is really pretty simple code. All we\u2019re doing here is toggling the value of the user can\u2019t change password switch. That\u2019s what the XOR command does. If the switch is on, XOR turns if off; if the switch is off, XOR turns it on. We\u2019re taking the current value of the userFlags attribute and toggling the user can\u2019t change password switch. Because we know this switch is off (remember the <B>If Not<\/B> statement we just used?), the XOR command will turn that switch on. Our variable objPasswordNoChangeFlag will then contain exactly the same values that are in the current userFlags attribute, with one exception: the user can\u2019t change password switch will now be on instead of off.<\/P>\n<P>Still with us? The rest of the script is easy. This line of code write the value of the variable objPasswordNoChangeFlag to the userFlags attribute:<\/P><PRE class=\"codeSample\">objUser.Put &#8220;userFlags&#8221;, objPasswordNoChangeFlag\n<\/PRE>\n<P>We then use the SetInfo command to write those changes to the user account. Just like that, local user Ken Myer will no longer have the right to change his password on the computer atl-ws-01.<\/P>\n<P>And what if wanted to <I>let<\/I> Ken Myer change his password? Hey, that\u2019s easy. All we have to do is check to see if the user can\u2019t change password switch is <I>on<\/I>, and then use XOR to turn it off:<\/P><PRE class=\"codeSample\">Const ADS_UF_PASSWD_CANT_CHANGE = &amp;H0040<\/p>\n<p>Set objUser = GetObject(&#8220;WinNT:\/\/atl-ws-01\/kenmyer&#8221;)<\/p>\n<p>If objUser.UserFlags AND ADS_UF_PASSWD_CANT_CHANGE Then\n    objPasswordNoChangeFlag = objUser.UserFlags XOR ADS_UF_PASSWD_CANT_CHANGE\n    objUser.Put &#8220;userFlags&#8221;, objPasswordNoChangeFlag \n    objUser.SetInfo\nEnd If\n<\/PRE>\n<P>The only difference is that we removed the word <I>Not<\/I> from our If-Then statement. That\u2019s because now we <I>want<\/I> to find instances where the switch is on, the better to turn it off.<\/P>\n<P>We agree: these bitmask attributes <I>are<\/I> confusing. If you\u2019d like a little more information (and a picture or two), you might check out <A href=\"http:\/\/null\/technet\/scriptcenter\/guide\/sas_scr_tspz.mspx\"><B>this portion<\/B><\/A> of the Microsoft Windows 2000 Scripting Guide. And, as promised, here are some other local user account properties that can be managed using the userFlags attribute:<\/P>\n<TABLE id=\"EXE\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Property<\/B><\/P><\/TD>\n<TD>\n<P class=\"lastInCell\"><B>Constant<\/B><\/P><\/TD>\n<TD>\n<P class=\"lastInCell\"><B>Value<\/B><\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">Logon script will be executed<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_SCRIPT<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H0001<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">Account is disabled<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_ACCOUNTDISABLE<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H0002<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">Account requires a home directory<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_HOMEDIR_REQUIRED<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H0008<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">Account is locked out<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_LOCKOUT<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H0010<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">Account does not require a password<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_PASSWD_NOTREQD<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H0020<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">User cannot change password<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_PASSWD_CANT_CHANGE<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H0040<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">Encrypted text password allowed<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H0080<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">Account password never expires<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_DONT_EXPIRE_PASSWD<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H10000<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">Smartcard required for logon<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_SMARTCARD_REQUIRED<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H40000<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">Password has expired<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">ADS_UF_PASSWORD_EXPIRED<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">&amp;H800000<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>If you get bored sometime, substitute these values into the user can\u2019t change password script and see what happens. (Of course, as always, we recommend you use a test machine &#8211; or at least a test account &#8211; when experimenting with scripts like this.)<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I configure a local user account so that the user can\u2019t change his or her password?&#8212; DC Hey, DC. The secret here lies in the mysterious userFlags attribute. We\u2019ll show you how to set a user account so that the user can\u2019t change his or her password, then we\u2019ll fill [&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":[23,24,3,5],"class_list":["post-70893","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-local-accounts-and-windows-nt-4-0-accounts","tag-other-directory-services","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I configure a local user account so that the user can\u2019t change his or her password?&#8212; DC Hey, DC. The secret here lies in the mysterious userFlags attribute. We\u2019ll show you how to set a user account so that the user can\u2019t change his or her password, then we\u2019ll fill [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70893","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=70893"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70893\/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=70893"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=70893"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=70893"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}