Script to change user passwords based on a random password maker

Hi,
i have the attached script provided here.
i am looking for a script that will input a list of users (txt\cvs) and will change their user password according to the attached script (a script made to make random passwords).
' Description: 		Auto Generates a password according to the following rules: 
' Be at least 8 positions in length but up to 10.
' Contain at least one English letter and one digit character
' Should not contain a digit character in the first and last position!(0-9)
' No special characters - lower case letters and digits only
' Must begin and end with a letter
 
Const MinLength = 8
Const MaxLength = 9
 
While ValidatePassword(strPassword) = False
	strPassword = GeneratePassword
Wend
 
CopyToClipboard strPassword
 
MsgBox strPassword 
 
Function GeneratePassword()
 
	strRndPwd = ""
	
	If MinLength = "" Or MaxLength = "" Then
		WScript.Echo "Min and max lengths are not defined. Please set MinLength and MaxLength globally."
		Exit Function
	End If
	
	Randomize
	intLength = Int((MaxLength - MinLength + 1) * Rnd + MinLength)
 
	Const AsciiLower = 32
	Const AsciiUpper = 126
 
	While Len(strRndPwd) <= intLength
		'Randomize
		strChr = Chr(Int((AsciiUpper - AsciiLower + 1) * Rnd + AsciiLower))
		If (Asc(strChr) >= 48 And Asc(strChr) <= 57) Or (Asc(strChr) >= 97 And Asc(strChr) <= 122) Then strRndPwd = strRndPwd & strChr
	Wend
 
	GeneratePassword = strRndPwd
End Function
 
Function ValidatePassword(strValPwd)
	Set objRegEx = CreateObject("VBScript.RegExp")
	boolValid = True
	' Check the length requirement
	If Len(strValPwd) < MinLength Or Len(strValPwd) > MaxLength Then boolValid = False
	' Look for an english character
	If boolValid = True Then
		objRegEx.Pattern = "[a-z]"
		Set colMatches = objRegEx.Execute(strValPwd)  
		If colMatches.Count = 0 Then boolValid = False
	End If
	' Look for a digit
	If boolValid = True Then
		objRegEx.Pattern = "[0-9]"
		Set colMatches = objRegEx.Execute(strValPwd)  
		If colMatches.Count = 0 Then boolValid = False
	End If
	' Look for a digit in the first or last position
	If boolValid = True Then
		strFirstChr = Left(strValPwd, 1)
		strLastChr = Right(strValPwd, 1)
		If IsNumeric(strFirstChr) Or IsNumeric(strLastChr) Then boolValid = False
	End If
	' Prevent specific words from being the password
	arrWords = Array( _
		"help", _
		"desk", _
		"hospital" _
	)
	For Each strWord In arrWords
		If InStr(strValPwd, strWord) > 0 Then boolValid = False
	Next
	' Return the valid code
	ValidatePassword = boolValid
End Function
 
Sub CopyToClipboard(strTextForClipboard)
	Set objIE = CreateObject("InternetExplorer.Application")
	objIE.Navigate("about:blank")
	objIE.document.parentwindow.clipboardData.SetData "text", strTextForClipboard
End Sub

Open in new window

johnnyjonathanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RobSampsonCommented:
Hi, to change a user's password, you can use:

Set objUser = GetObject("LDAP://cn=KenMyer,ou=Finance,dc=fabrikam,dc=com")
objUser.SetPassword("i5A2sj*!")

which comes from
http://www.microsoft.com/technet/scriptcenter/resources/qanda/oct04/hey1015.mspx

So, if you read through a CSV, and use an LDAP search to bind to the user, you can change the password.....

I'm short of time right now...if you get stuck, I'll help out later...

Regards,

Rob.
0
johnnyjonathanAuthor Commented:
Hi Rob,
thanks for the direction -  i've tried ading the code below to the script so it will read from each line inside the txt file but i got the error -

Microsoft VBScript runtime error: Input past end of file
anything i'm doing wrong?
the txt file holds all CN names.

Set Userlist = CreateObject("Scripting.FileSystemObject")
Set Disabletemp = Userlist.OpenTextFile("d:\Userlist.txt")
	Do While Not Disabletemp.AtEndOfStream
		Disable =  Disabletemp.readline
		Set objUser = GetObject (Disabletemp.readline)
		objUser.SetPassword(strPassword)
	Loop 
Disabletemp.close
Disable.close
 
MsgBox Done

Open in new window

0
RobSampsonCommented:
Hi, it looks like the only thing you're doing wrong there is using the ReadLine method twice, which means you'll always skip one line, and may end up reading past the end of the file as well.

Also, if you're text file holds only the CN property of each user, you're going to have to search AD for the full distinguished name, so I've added that.

So it now should read a line, search AD for the user, bind to the user, generate a password using your original code, then set the password.

Regards,

Rob.
Const MinLength = 8
Const MaxLength = 9
 
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("d:\Userlist.txt")
While Not objFile.AtEndOfStream
	strUserCN = Trim(objFile.ReadLine)
	If strUserCN <> "" Then
		strUserADsPath =  Get_LDAP_User_Properties("user", "cn", strUserCN, "adsPath")
		If Left(strUserADsPath, 7) = "LDAP://" Then
			Set objUser = GetObject(strUserADsPath)
 
			' Description: 		Auto Generates a password according to the following rules: 
			' Be at least 8 positions in length but up to 10.
			' Contain at least one English letter and one digit character
			' Should not contain a digit character in the first and last position!(0-9)
			' No special characters - lower case letters and digits only
			' Must begin and end with a letter
			
			strPassword = ""
			While ValidatePassword(strPassword) = False
				strPassword = GeneratePassword
			Wend
			
			objUser.SetPassword(strPassword)
		Else
			MsgBox "Could not find adsPath for " & strUserCN
		End If
	End If
Loop 
objFile.Close
 
MsgBox "Done"
 
Function GeneratePassword()
 
	strRndPwd = ""
	
	If MinLength = "" Or MaxLength = "" Then
		WScript.Echo "Min and max lengths are not defined. Please set MinLength and MaxLength globally."
		Exit Function
	End If
	
	Randomize
	intLength = Int((MaxLength - MinLength + 1) * Rnd + MinLength)
 
	Const AsciiLower = 32
	Const AsciiUpper = 126
 
	While Len(strRndPwd) <= intLength
		'Randomize
		strChr = Chr(Int((AsciiUpper - AsciiLower + 1) * Rnd + AsciiLower))
		If (Asc(strChr) >= 48 And Asc(strChr) <= 57) Or (Asc(strChr) >= 97 And Asc(strChr) <= 122) Then strRndPwd = strRndPwd & strChr
	Wend
 
	GeneratePassword = strRndPwd
End Function
 
Function ValidatePassword(strValPwd)
	Set objRegEx = CreateObject("VBScript.RegExp")
	boolValid = True
	' Check the length requirement
	If Len(strValPwd) < MinLength Or Len(strValPwd) > MaxLength Then boolValid = False
	' Look for an english character
	If boolValid = True Then
		objRegEx.Pattern = "[a-z]"
		Set colMatches = objRegEx.Execute(strValPwd)  
		If colMatches.Count = 0 Then boolValid = False
	End If
	' Look for a digit
	If boolValid = True Then
		objRegEx.Pattern = "[0-9]"
		Set colMatches = objRegEx.Execute(strValPwd)  
		If colMatches.Count = 0 Then boolValid = False
	End If
	' Look for a digit in the first or last position
	If boolValid = True Then
		strFirstChr = Left(strValPwd, 1)
		strLastChr = Right(strValPwd, 1)
		If IsNumeric(strFirstChr) Or IsNumeric(strLastChr) Then boolValid = False
	End If
	' Prevent specific words from being the password
	arrWords = Array( _
		"help", _
		"desk", _
		"hospital" _
	)
	For Each strWord In arrWords
		If InStr(strValPwd, strWord) > 0 Then boolValid = False
	Next
	' Return the valid code
	ValidatePassword = boolValid
End Function
 
Sub CopyToClipboard(strTextForClipboard)
	Set objIE = CreateObject("InternetExplorer.Application")
	objIE.Navigate("about:blank")
	objIE.document.parentwindow.clipboardData.SetData "text", strTextForClipboard
End Sub
 
Function Get_LDAP_User_Properties(strObjectType, strSearchField, strObjectToGet, strCommaDelimProps)
      
      ' This is a custom function that connects to the Active Directory, and returns the specific
      ' Active Directory attribute value, of a specific Object.
      ' strObjectType: usually "User" or "Computer"
      ' strSearchField: the field by which to seach the AD by. This acts like an SQL Query's WHERE clause.
      '				It filters the results by the value of strObjectToGet
      ' strObjectToGet: the value by which the results are filtered by, according the strSearchField.
      '				For example, if you are searching based on the user account name, strSearchField
      '				would be "samAccountName", and strObjectToGet would be that speicific account name,
      '				such as "jsmith".  This equates to "WHERE 'samAccountName' = 'jsmith'"
      '	strCommaDelimProps: the field from the object to actually return.  For example, if you wanted
      '				the home folder path, as defined by the AD, for a specific user, this would be
      '				"homeDirectory".  If you want to return the ADsPath so that you can bind to that
      '				user and get your own parameters from them, then use "ADsPath" as a return string,
      '				then bind to the user: Set objUser = GetObject("LDAP://" & strReturnADsPath)
      
      ' Now we're checking if the user account passed may have a domain already specified,
      ' in which case we connect to that domain in AD, instead of the default one.
      If InStr(strObjectToGet, "\") > 0 Then
            arrGroupBits = Split(strObjectToGet, "\")
            strDC = arrGroupBits(0)
            strDNSDomain = strDC & "/" & "DC=" & Replace(Mid(strDC, InStr(strDC, ".") + 1), ".", ",DC=")
            strObjectToGet = arrGroupBits(1)
      Else
      ' Otherwise we just connect to the default domain
            Set objRootDSE = GetObject("LDAP://RootDSE")
            strDNSDomain = objRootDSE.Get("defaultNamingContext")
      End If
 
      strBase = "<LDAP://" & strDNSDomain & ">"
      ' Setup ADO objects.
      Set adoCommand = CreateObject("ADODB.Command")
      Set adoConnection = CreateObject("ADODB.Connection")
      adoConnection.Provider = "ADsDSOObject"
      adoConnection.Open "Active Directory Provider"
      adoCommand.ActiveConnection = adoConnection
 
 
      ' Filter on user objects.
      'strFilter = "(&(objectCategory=person)(objectClass=user))"
      strFilter = "(&(objectClass=" & strObjectType & ")(" & strSearchField & "=" & strObjectToGet & "))"
 
      ' Comma delimited list of attribute values to retrieve.
      strAttributes = strCommaDelimProps
      arrProperties = Split(strCommaDelimProps, ",")
 
      ' Construct the LDAP syntax query.
      strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
      adoCommand.CommandText = strQuery
      ' Define the maximum records to return
      adoCommand.Properties("Page Size") = 100
      adoCommand.Properties("Timeout") = 30
      adoCommand.Properties("Cache Results") = False
 
      ' Run the query.
      Set adoRecordset = adoCommand.Execute
      ' Enumerate the resulting recordset.
      strReturnVal = ""
      Do Until adoRecordset.EOF
          ' Retrieve values and display.    
          For intCount = LBound(arrProperties) To UBound(arrProperties)
                If strReturnVal = "" Then
                      strReturnVal = adoRecordset.Fields(intCount).Value
                Else
                      strReturnVal = strReturnVal & VbCrLf & adoRecordset.Fields(intCount).Value
                End If
          Next
          ' Move to the next record in the recordset.
          adoRecordset.MoveNext
      Loop
 
      ' Clean up.
      adoRecordset.Close
      adoConnection.Close
      Get_LDAP_User_Properties = strReturnVal
 
End Function

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

johnnyjonathanAuthor Commented:
Hi Rob,
thanks for your explanation.
i understand better now what i did wrong.

however, i get the attached error when i try to use the user name or the DN.
something i'm missing?

Untitled.jpg
0
johnnyjonathanAuthor Commented:
Sorry, my mistake.
i didn't saw that there was a "DO" missing in line 6.
though now it gives me errors for some users "could not find adspath". the users i'm running the search on are from diffrent OU's
 
0
RobSampsonCommented:
Hi Johnny,

Sorry for my delay.  The script is looking through AD by the CN of the user, that you have listed in the text file.  It would probably be best to use the samAccountName (user logon name) of the users, as the content of the text file, then change this line:

            strUserADsPath =  Get_LDAP_User_Properties("user", "cn", strUserCN, "adsPath")


to this

            strUserADsPath =  Get_LDAP_User_Properties("user", "samAccountName", strUserCN, "adsPath")

Regards,

Rob.
0
johnnyjonathanAuthor Commented:
Works flawless with the last comment!
Thank you very much!  Deserve every point granted
0
RobSampsonCommented:
Hi, that's great. Thanks for the grade.  FYI, using the samAccountName is also best because the AD makes sure that each one is unique, so you will affect only one account at a time.

Regards,

Rob.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.