Script to set 'Password never expires' flag

Discussion in 'Active Directory' started by Marsha, Nov 17, 2004.

  1. Marsha

    Marsha Guest

    Does anyone have a script that can set the 'Password Never Expires' flag for
    all users in the domain? I need to set the attribute for everyone and am not
    very good at scripting. I can get it to work for a specific user, but I want
    it to effect the whole domain.

    Thanks,
    Marsha
     
    Marsha, Nov 17, 2004
    #1
    1. Advertisements

  2. Marsha

    Paul Bergson Guest

    Try code below it should bring back all your users names and placed in the
    field txtName. Make sure to change yourdomain to your domain name, in the
    commandtext object defn. This is written in vbs. You should be able to
    place your single instance that works in the ''' your code goes here
    section.

    BE
    CAREFUL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !!!!!!!!!!!!!!!!!!!!!!!!






    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Main Code of Program '
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Set objConnection = CreateObject("ADODB.Connection") ' Create a Connection
    object in memory
    objConnection.Open "Provider=ADsDSOObject;" ' Open the Connection
    object using the ADSI OLE DB provider

    Set objCommand = CreateObject("ADODB.Command") 'Create an ADO Command
    object in memory, and assign the Command _
    objCommand.ActiveConnection = objConnection ' object's
    ActiveConnection property to the Connection object

    objCommand.Properties("Page Size") = 100
    objCommand.Properties("Size Limit") = 3000 ' set for 3000 user
    objects

    objCommand.CommandText = _

    "<LDAP://dc=YOURDOMAIN,dc=com>;(objectCategory=user);sAMAccountName,distingu
    ishedName,name,whenCreated,homeDirectory,scriptPath,displayName;subtree"


    Set objRecordSet = objCommand.Execute ' Run the query by
    calling the Execute method of the Command object


    While Not objRecordSet.EOF
    txtName = lcase(objRecordSet.Fields("distinguishedName")) '
    Access each record in objRecordSet


    ''' Your code goes here


    objRecordSet.MoveNext
    Wend
     
    Paul Bergson, Nov 17, 2004
    #2
    1. Advertisements

  3. Hi,

    The script below uses ADO to retrieve the distinguishedName and
    userAccountControl attributes for all users in the domain. You "And"
    userAccountControl with a bit mask (ADS_UF_DONT_EXPIRE_PASSWD) to check if
    the bit is set. A non-zero result indicates the bit is set. In the code
    below, if the result is zero, we know the bit is not set, so the password
    can expire and we must set the bit. The bit is set by "Or'ing"
    userAccountControl with the bit mask. To modify the user you must bind to
    the user object, which is why distinguishedName is also retrieved.


    ' Program to set "Password never expires" for all users in a domain.
    Option Explicit

    Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000

    Dim objRootDSE, strDNSDomain, objCommand, objConnection
    Dim strBase, strFilter, strAttributes, strQuery, objRecordSet
    Dim strDN, lngFlag, objUser

    ' Determine DNS domain name.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")

    ' Use ADO to search Active Directory.
    Set objCommand = CreateObject("ADODB.Command")
    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
    objCommand.ActiveConnection = objConnection
    strBase = "<LDAP://" & strDNSDomain & ">"

    ' Search for all users.
    strFilter = "(&(objectCategory=person)(objectClass=user))"
    strAttributes = "distinguishedName,userAccountControl"
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
    objCommand.CommandText = strQuery
    objCommand.Properties("Page Size") = 100
    objCommand.Properties("Timeout") = 30
    objCommand.Properties("Cache Results") = False
    Set objRecordSet = objCommand.Execute

    ' Enumerate all users.
    Do Until objRecordSet.EOF
    strDN = objRecordSet.Fields("distinguishedName")
    ' Check if password can expire.
    lngFlag = objRecordSet.Fields("userAccountControl")
    If (lngFlag And ADS_UF_DONT_EXPIRE_PASSWD) = 0 Then
    ' Flag not set. Password can expire. Bind to user and set flag.
    Set objUser = GetObject("LDAP://" & strDN)
    lngFlag = lngFlag Or ADS_UF_DONT_EXPIRE_PASSWD
    objUser.Put "userAccountControl", lngFlag
    objUser.SetInfo
    Wscript.Echo "User modified: " & strDN
    End If
    objRecordSet.MoveNext
    Loop

    ' Clean up.
    objConnection.Close
    Set objUser = Nothing
    Set objRootDSE = Nothing
    Set objCommand = Nothing
    Set objConnection = Nothing
    Set objRecordSet = Nothing
     
    Richard Mueller [MVP], Nov 17, 2004
    #3
  4. Marsha

    Marsha Guest

    Thanks for the script. The only problem I'm having is a 'general access
    denied' error on the objuser.setinfo command in my test lab. The only
    information I am finding about this error is regarding IIS which I am not
    running. If I attempt to run the script in my live environment, I get 'The
    server is unwilling to process the request'. The account I am using to run
    the script is a member of domain, enterprise, and schema admins. It appeared
    to set about 5 accounts and then produced the server is unwilling to process
    error above. Any ideas that I could try or settings I could check?
     
    Marsha, Nov 19, 2004
    #4
  5. Hi,

    I did a brief test (I developed the script months ago) and had no problem.
    The fact that the script appears to work for 5 users, then raises an error
    seems to indicate either a permission problem or a conflict with some other
    setting. I didn't want to change this setting for all my users, so perhaps
    there could also be some server issue.

    I also tested with a user that has "User must change password at next
    logon". You are not allowed to have both settings, but after the program
    ran, this user had "User must change password at next logon" unchecked and
    "Password never expires" checked.

    Can you tell which user object raised the error and compare this object with
    the ones that were modified successfully? Maybe you can see a difference.

    I'm still looking.

    --
    Richard
    Microsoft MVP Scripting and ADSI
    HilltopLab web site - http://www.rlmueller.net
    --

     
    Richard Mueller [MVP], Nov 19, 2004
    #5
  6. Marsha

    Marsha Guest

    Hi,
    Well, 4 of the 5 were in the users container and the other one was one of my
    collegues in a separate OU. I unchecked the box for all and ran the script
    again. This time, I got the 'server unwilling to process the request' error
    immediately. I agree with you, it seems to be a permissions issue. I will
    check the domain controller policies, etc. If you think of anything, please
    let me know.

    Thanks,
    Marsha

     
    Marsha, Nov 19, 2004
    #6
  7. Marsha

    Al Mulnick Guest

    Marsha, what was the original requirement?

    You need to set all passwords to never expire for all users? Whatever for
    (test lab I assume)?

    How many domains are there? If more than one (root/child) you may want to
    short circuit the part about finding the naming context and hard code it to
    see if you get better results.


    Al



     
    Al Mulnick, Nov 20, 2004
    #7
  8. Marsha

    Marsha Guest

    Hi,

    The original requirement is to set the 'password never expires' flag for all
    users so that we can control the domain password policy's expiration
    settings. The password policy will be turned on and we'll then control it at
    the user level. If you have a better suggestion, please let me know. This
    was the only way I could think of to not apply the password policy expiration
    settings all at once. There's only one domain, so its pretty
    straightforward. Any help would be greatly appreciated.

     
    Marsha, Nov 20, 2004
    #8
  9. Marsha

    Al Mulnick Guest

    So if I follow you correctly, you're wanting to set all of the user
    passwords to never expire, apply the policy to the domain, then go back and
    de-select that check box one by one?

    Wouldn't it be better to select the ones that should never expire and let
    the rest of them follow the policy?

    Wouldn't it be better to use the ADU&C to do this? I'm assuming W2K3 which
    has the ability to select multiple users and modify that field. You won't
    be able to use search for this although you can select all you can see.


    If it's only one domain, then the script likely found the correct
    information so that may not be it. I had read it to mean that you had
    restored this in the lab and figured there may be other domains in your
    forest. But if this is a single-forest/single-domain then that's not it.j

    It may be that you want to drop back and use a different method if you still
    want to set all accounts to never expire. Start by getting the user DN's
    and then for each of them use dsmod user
    http://www.microsoft.com/windowsxp/...owsxp/home/using/productdoc/en/dsmod_user.asp

    You'll see a nice explanation by Richard how this might work and even an
    example to get the DN's into a file. If you go that route, you can put them
    a file, then modify the file to be a cmd file and put the dsmod query around
    the DN on each line I would imagine.

    Just theory though. You could also use the dsquery tool to grab the DN of
    the users and then pipe it to the dsmod command. Keeps you from having to
    learn script.
     
    Al Mulnick, Nov 20, 2004
    #9
  10. Marsha

    Marsha Guest

    Al,

    Thanks for taking the time to respond and give some good advice. We're
    running Win2k still. And i did restore into our test lab, but its giving the
    same error in live. Yes, it would make sense just to set the 'password never
    expires' for only the accounts that we never want to expire, but there is
    politics behind this. Mgmt does not want to turn it on for everyone all at
    once. We have to hold hands department by department, so that is the reason
    for attempting to use this script. I'll keep trying and check into your
    suggestions. if you think of anything else, please let me know.

    Thanks!

     
    Marsha, Nov 22, 2004
    #10
  11. Marsha

    Al Mulnick Guest

    What's your comfort level then? Is DSMOD going to do what you want?
    Or is scripting the way you want to proceed?

    Al
     
    Al Mulnick, Nov 23, 2004
    #11
  12. Marsha

    Marsha Guest

    Well, i don't have a real comfort level with either, but i looked into dsmod
    and it seems a little more difficult for me, but either will work fine, if I
    can in fact get them to work. I just don't understand why I can't get past
    the 'general access denied' or 'server is unwilling to process request' error
    messages. Which, to you, would be easier?

     
    Marsha, Nov 23, 2004
    #12
  13. Marsha

    Al Mulnick Guest

    Scripting typically.
    In that script that was sent before, did you try changing this line: strBase
    = "<LDAP://" & strDNSDomain & ">" to be something like
    strBase = "LDAP://dc=yourdomain,dc=com"
    and did you get the same results?


    Al
     
    Al Mulnick, Nov 24, 2004
    #13
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.