http://www.activexperts.com/activmonitor/windowsmanagement/adminscripts/usersgroups/localusers/#ConfigLocalUserPassNeverExp.htm
Wanting to try it out, I ran the following script after creating an account called test and manually setting this flag via the user's GUI from the computer management console.
Set objNetwork = WScript.CreateObject("WScript.Network")
strComputer = CStr(objNetwork.ComputerName)
WScript.Echo strComputer
Set objUser = GetObject("WinNT://" & strComputer & "/test")
objUserFlags = objUser.Get("UserFlags")
WScript.Echo objUserFlagsAs it turned out, it worked! I was stoked. I love when old problems finally get solved. It's got such a sense of resolution. As it turns out, if you want to dig into the enum used for these values, Microsoft has the UserAccessControl definition here:
http://msdn.microsoft.com/en-us/library/aa772300(VS.85).aspx
Denoted specifically in the link are these notes:
"The ADS_USER_FLAG_ENUM enumeration defines the flags used for setting user properties in the directory. These flags correspond to values of the userAccountControl attribute in Active Directory when using the LDAP provider, and the userFlags attribute when using the WinNT system provider."
Here the explicit enumeration:
typedef enum {
ADS_UF_SCRIPT = 1, // 0x1
ADS_UF_ACCOUNTDISABLE = 2, // 0x2
ADS_UF_HOMEDIR_REQUIRED = 8, // 0x8
ADS_UF_LOCKOUT = 16, // 0x10
ADS_UF_PASSWD_NOTREQD = 32, // 0x20
ADS_UF_PASSWD_CANT_CHANGE = 64, // 0x40
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 128, // 0x80
ADS_UF_TEMP_DUPLICATE_ACCOUNT = 256, // 0x100
ADS_UF_NORMAL_ACCOUNT = 512, // 0x200
ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 2048, // 0x800
ADS_UF_WORKSTATION_TRUST_ACCOUNT = 4096, // 0x1000
ADS_UF_SERVER_TRUST_ACCOUNT = 8192, // 0x2000
ADS_UF_DONT_EXPIRE_PASSWD = 65536, // 0x10000
ADS_UF_MNS_LOGON_ACCOUNT = 131072, // 0x20000
ADS_UF_SMARTCARD_REQUIRED = 262144, // 0x40000
ADS_UF_TRUSTED_FOR_DELEGATION = 524288, // 0x80000
ADS_UF_NOT_DELEGATED = 1048576, // 0x100000
ADS_UF_USE_DES_KEY_ONLY = 2097152, // 0x200000
ADS_UF_DONT_REQUIRE_PREAUTH = 4194304, // 0x400000
ADS_UF_PASSWORD_EXPIRED = 8388608, // 0x800000
ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 16777216 // 0x1000000
} ADS_USER_FLAG_ENUM;The one I had been looking for all along was
ADS_UF_DONT_EXPIRE_PASSWD = 65536, // 0x10000
You can compound these values rather easily if you don't know what the actual flag you need is. Here's an example using some simple numbers in hex format:
hex1 = &h1
hex2 = &h10
WScript.Echo CInt(hex1) 'Will evaluate to 1
Wscript.Echo CInt(hex2) 'will evaluate to 16
WScript.Echo hex1 + hex2
The output for this script is
1
16
17
For instance, if you want to combine the ADS_UF_PASSWD_CANT_CHANGE and the ADS_UF_DONT_EXPIRE_PASSWD values, do this in VBScript:
Const ADS_UF_PASSWD_CANT_CHANGE = 0&40
Const ADS_UF_DONT_EXPIRE_PASSWD = 0&10000
Dim customUserFlag = ADS_UF_PASSWD_CANT_CHANGE + ADS_UF_DONT_EXPIRE_PASSWD
Another way you can accomplish this is to use the OR function. For example:
Const ADS_UF_PASSWD_CANT_CHANGE = 0&40 '64
Const ADS_UF_DONT_EXPIRE_PASSWD = 0&10000 '65356
Dim customUserFlag = ADS_UF_PASSWD_CANT_CHANGE + ADS_UF_DONT_EXPIRE_PASSWD
This will output:
&h10040 = 65600
So, you can simply add constants, as outlined based on the enumeration, and compound those based on the value you want. Or, you can use the OR technique outlined in the script above.
When I applied this back to my user account I knew I only had 5 controls that I could manipulate via the GUI. After combining all the options, here's what I concluded are the most direct value combinations accessible via the interface. For each decimal representation I provide the equivalent hex and binary values. These lists indicate which of the 5 controls are set (checked), unset (unchecked) or disabled (inactive).
513 - &h201 - 1000000001
-unset:
-- User must change password at next logon
-- User cannot change password
-- password never expires
-- account is locked out
-disabled:
-- account is locked out
515 - &h201 - 1000000011
-set
-- Account is disabled-unset
-- User must change password at next logon
-- User cannot change password
-- password never expires
-disabled:
-- account is locked out
579 - &h243 - 1001000011
-set
-- Account is disabled
-- User cannot change password
-unset
-- password never expires
-disabled:
-- User must change password at next logon
-- account is locked out
66051 - &h10203 - 10000001000000011
-set
-- Account is disabled
-- password never expires
-unset
-- User cannot change password
-disabled:
-- User must change password at next logon
-- account is locked out
66115 - &h10243 - 10000001001000011
-set
-- Account is disabled
-- User cannot change password
-- password never expires
-disabled:
-- User must change password at next logon
-- account is locked out
8389121 - &h800201 - 100000000000001000000001
-set
-- User must change password at next logon
-unset
-- Account is disabled
-disabled:
-- User cannot change password
-- password never expires
-- account is locked out
8389123 - &h800203 - 100000000000001000000011
-set
-- User must change password at next logon
-- Account is disabled
Account is disabled
-disabled:
-- User cannot change password
-- password never expires
-- account is locked out
From this list, it is easy to see how the bits work for this enumeration.
Although it is clear there are additional options that can be explored to set up more advanced user accounts, this covers the majority of what I needed to learn about the Password never expires option.
Below is a script that will create a new account and set the password to never expire. After the account is created it will display the flag value. If you are using cscript as your default shell interface, it will display in the cli, whereas a default of wscript will prompt a single dialog. If you are unsure of which you are using, set it to wscript (it's easier to know) by starting a cmd shell and typing:wscript //h:wscript
then hitting [Enter]. Here is the script itself'Declare constants for non-expiring password
Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
'create local machine reference and get machine name
Set objNetwork = WScript.CreateObject("WScript.Network")
strComputer = CStr(objNetwork.ComputerName)
'create reference to WinNT user store (localmachine)
Set colAccounts = GetObject("WinNT://" & strComputer & "")
'Create new user account
Set objUser = colAccounts.Create("user", "Admin2")
'Set passwordobj
User.SetPassword("H@rdP@ssw0rd")
'Retrieve and set UserFlagsobjPasswordExpirationFlag = ADS_UF_DONT_EXPIRE_PASSWD
objUser.Put "userFlags", objPasswordExpirationFlag
objUser.SetInfo
'Validate userFlagsobjUserFlags = objUser.Get("UserFlags")
WSCript.Echo objUserFlags
0 comments:
Post a Comment