itsmevic
asked on
Account Lockouts
Hello,
I need help in creating a script that monitors a particular threshold of lockouts. For example, let's say my threshold for lockouts presently is 2 lockouts in an eight hour period. In an example scenerio, I have a user that has been locked out 4 times in one day (within 8 hours), the script would then catch that and then send out an email alert, noting this, and the report might look like this below:
Account Account Name DN Description PC Name IP (if possible)
And in the Subject line of the email say: "These accounts surpass the 2 lockout attempt
threshold"
I would assume that basic logic behind this is that it would run it's scan, create a text file and based off the scan bounce it's finding's off of the master text file each time the script is ran. Or scan through the lockout's folder on the log server for that day.
Any help with this is GREATLY appreciated.
I need help in creating a script that monitors a particular threshold of lockouts. For example, let's say my threshold for lockouts presently is 2 lockouts in an eight hour period. In an example scenerio, I have a user that has been locked out 4 times in one day (within 8 hours), the script would then catch that and then send out an email alert, noting this, and the report might look like this below:
Account Account Name DN Description PC Name IP (if possible)
And in the Subject line of the email say: "These accounts surpass the 2 lockout attempt
threshold"
I would assume that basic logic behind this is that it would run it's scan, create a text file and based off the scan bounce it's finding's off of the master text file each time the script is ran. Or scan through the lockout's folder on the log server for that day.
Any help with this is GREATLY appreciated.
ASKER
Hi Rob, good to hear from you again. Here is a sample of the lockout log format:
USER,04/30/2009,04:09:20,D C-1,PCNAME
USER,04/30/2009,04:09:20,D C-1,PCNAME
USER,04/30/2009,04:09:20,D C-2,PCNAME
USER,04/30/2009,04:09:20,D C-10,PCNAM E
USER,04/30/2009,04:09:20,D C-1,PCNAME
USER,04/30/2009,04:09:20,D
USER,04/30/2009,04:09:20,D
USER,04/30/2009,04:09:20,D
USER,04/30/2009,04:09:20,D
USER,04/30/2009,04:09:20,D
Hmmm, so that's a flat text file, not the events from the Event Viewer? In that case, we won't need to query the Event Log, but we should be able to read that data into a disconnected recordset, then perform filters on it.....I'll see what I can create, and you can see if that suits....
Regards,
Rob.
Regards,
Rob.
ASKER
I basically already know the triggers I'll need to use i.e. any account that has been locked out more than 2 times in an 8 hour period. If the script detects this, then a formatted email is sent out providing the following information to the receipant:
acct, acct name, dn, description, pc name
then for the subject line of the alert email: "these account(s) exceed the lockout threshold of 2"
acct, acct name, dn, description, pc name
then for the subject line of the alert email: "these account(s) exceed the lockout threshold of 2"
ASKER
Ok cool Rob. It is exactly as you described above, all of my logs are all just flat text files.
OK, so here's a start....it doesn't report any time frames, it just counts the total lockouts for each user from the log file.
See how that goes, and if would like extra information output, let me know.
Regards,
Rob.
See how that goes, and if would like extra information output, let me know.
Regards,
Rob.
If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
strPath = Wscript.ScriptFullName
strCommand = "%comspec% /k cscript """ & strPath & """"
Set objShell = CreateObject("Wscript.Shell")
objShell.Run(strCommand), 1, True
Wscript.Quit
End If
strLogFile = Replace(WScript.ScriptFullName, WScript.ScriptName, "") & "Account_Lockouts_Log.txt"
WScript.Echo "Parsing log file " & strLogFile & VbCrLf & VbCrLf
Const ForReading = 1
Const adVarChar = 200
Const MaxCharacters = 255
Const adDouble = 5
Set objData = CreateObject("ADOR.Recordset")
objData.Fields.Append "Username", adVarChar, MaxCharacters
objData.Fields.Append "DateTime", adVarChar, MaxCharacters
objData.Fields.Append "DC", adVarChar, MaxCharacters
objData.Fields.Append "PC", adVarChar, MaxCharacters
objData.Open
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strLogFile, ForReading, False)
strUsers = ";"
While Not objFile.AtEndOfStream
strLine = objFile.ReadLine
If strLine <> "" Then
arrLine = Split(LCase(strLine), ",")
objData.AddNew
objData("Username") = Trim(arrLine(0))
objData("DateTime") = Trim(arrLine(1)) & " " & Trim(arrLine(2))
objData("DC") = Trim(arrLine(3))
objData("PC") = Trim(arrLine(4))
objData.Update
If strUsers = "" Then
strUsers = arrLine(0) & ";"
Else
If InStr(strUsers, ";" & arrLine(0) & ";") = 0 Then strUsers = strUsers & arrLine(0) & ";"
End If
End If
Wend
objFile.Close
If Left(strUsers, 1) = ";" Then strUsers = Mid(strUsers, 2)
If Right(strUsers, 1) = ";" Then strUsers = Left(strUsers, Len(strUsers) - 1)
For Each strUser In Split(strUsers, ";")
objData.Filter = "Username='" & strUser & "'"
objData.MoveFirst
intLockoutCount = 0
While Not objData.EOF
intLockoutCount = intLockoutCount + 1
objData.MoveNext
Wend
WScript.Echo strUser & " has been locked out " & intLockoutCount & " times."
Next
WScript.Echo VbCrLf & VbCrLf & "Done"
ASKER
Hi Rob,
Unfortunately the script above appears to be erroring out on me for some reason. One thing I noticed is that it's not like your other scripts where you open a Search dialog box, then select a single file and carry on from there. In this script, the file is specified at:
strLogFile = Replace(WScript.ScriptFull Name, WScript.ScriptName, "") & "Account_Lockouts_Log.txt"
After realizing this, I changed it to reflect a log file name in my Lockout folder i.e. DCNAMEActLockout_11.ActLoc k, re-ran the script and got the error:
\\log-server\logs\ActLocko ut\logs\Lo ckout.vbs( 26, 1) Microsoft VBScript runtime error: File not found.
Below is a visual hopefully this will shed some light on the whole thing.
Lockout.bmp
Unfortunately the script above appears to be erroring out on me for some reason. One thing I noticed is that it's not like your other scripts where you open a Search dialog box, then select a single file and carry on from there. In this script, the file is specified at:
strLogFile = Replace(WScript.ScriptFull
After realizing this, I changed it to reflect a log file name in my Lockout folder i.e. DCNAMEActLockout_11.ActLoc
\\log-server\logs\ActLocko
Below is a visual hopefully this will shed some light on the whole thing.
Lockout.bmp
OK, so let's just try and point it to a single file, by changing this:
strLogFile = Replace(WScript.ScriptFull Name, WScript.ScriptName, "") & "Account_Lockouts_Log.txt"
to this
strLogFile = "\\log-server\logs\actLock out\Logs\D C1-100ActL ockout_27. ActLock"
The whole Replace(WScript.ScriptFull Name, WScript.ScriptName, "") in the original script only refers to the parent folder that the script is running from. I use it for a relative paths.
Regards,
Rob.
strLogFile = Replace(WScript.ScriptFull
to this
strLogFile = "\\log-server\logs\actLock
The whole Replace(WScript.ScriptFull
Regards,
Rob.
ASKER
Yep that worked great. Command prompt appeared went through that DC's lockout reports with no problems.
Is it possible to do this with the script?
1.) Instead having to manually enter in the file name into the script, can we set it to scan all lockout files FOR THAT DATE in that AcctLockout folder? (This would save a ton of time rather than having to manually input each individual log file you needed to check.)
2.) Adding the logic within the script to set a threshold trigger. That trigger being any account that has had more than 2 lockouts in an 8 hour period.
3.) For it to produce an alert email if it finds accounts that that have gone over 2 lockouts in an 8 hour period. If found, to fire out an email alert providing this in the email:
Acct Name, DN, Description, PC Name
Crossin' my fingers on this one ( - :
Is it possible to do this with the script?
1.) Instead having to manually enter in the file name into the script, can we set it to scan all lockout files FOR THAT DATE in that AcctLockout folder? (This would save a ton of time rather than having to manually input each individual log file you needed to check.)
2.) Adding the logic within the script to set a threshold trigger. That trigger being any account that has had more than 2 lockouts in an 8 hour period.
3.) For it to produce an alert email if it finds accounts that that have gone over 2 lockouts in an 8 hour period. If found, to fire out an email alert providing this in the email:
Acct Name, DN, Description, PC Name
Crossin' my fingers on this one ( - :
Yeah, I'm pretty sure all of the above is possible....certainly the first two, although for point 1, does the file name include the full date, or should we check by created date or last modified date? Created date should be good enough I would think.
For point 3, does the log file include the full DN path for each user, or is it samAccountName only? I only ask so that I can find out how to find each user....
Regards,
Rob.
For point 3, does the log file include the full DN path for each user, or is it samAccountName only? I only ask so that I can find out how to find each user....
Regards,
Rob.
ASKER
That's a great question.
Presently the naming format for my lockedout files is:
"DomainControllerNameActLo ckout_27.A ctlock
The 27 represents the day of the month. However since this ActLockout folder contains all lockout logs from Jan 1, 2009 up until now, there would be other 27's listed in log file names as well, so I think the best bet would be to do it by create date since I feel that would be most accurate in this case.
For point 3, the present lockout format for the log file is this:
username,date,time,dc,comp uter name
it does not include full DN path.
Thanks again for your help Rob!
Presently the naming format for my lockedout files is:
"DomainControllerNameActLo
The 27 represents the day of the month. However since this ActLockout folder contains all lockout logs from Jan 1, 2009 up until now, there would be other 27's listed in log file names as well, so I think the best bet would be to do it by create date since I feel that would be most accurate in this case.
For point 3, the present lockout format for the log file is this:
username,date,time,dc,comp
it does not include full DN path.
Thanks again for your help Rob!
Hello again,
OK, so that required a bit of a rewrite...and I hope I've got your output correct....see how this script goes for you....There's no email yet, and no account threshold either, but both are easier to put in. I may not have any more time today, so I might have to finish it tomorrow.
Regards,
Rob.
OK, so that required a bit of a rewrite...and I hope I've got your output correct....see how this script goes for you....There's no email yet, and no account threshold either, but both are easier to put in. I may not have any more time today, so I might have to finish it tomorrow.
Regards,
Rob.
Set objShell = CreateObject("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
strPath = Wscript.ScriptFullName
strCommand = "%comspec% /k cscript """ & strPath & """"
objShell.Run(strCommand), 1, True
Wscript.Quit
End If
strLogFolder = "\\log-server\logs\actLockout\Logs\"
'strLogFolder = Replace(WScript.ScriptFullName, WScript.ScriptName, "")
Const ForReading = 1
Const adVarChar = 200
Const MaxCharacters = 255
Const adDouble = 5
strShortDate = objShell.RegRead("HKCU\Control Panel\International\sShortDate")
If InStr(LCase(strShortDate), "d") < InStr(LCase(strShortDate), "m") Then
strDateFormat = "dd/mm/yyyy"
Else
strDateFormat = "mm/dd/yyyy"
End If
strDate = InputBox("Please enter the date of the files that you want to search" & VbCrLf & _
"in " & strDateFormat & " format:", "Date to Search", strDateFormat)
If strDate <> "" And strDate <> strDateFormat Then
dteDateFrom = CDate(strDate & " 00:00:00 AM")
dteDateTo = CDate(strDate & " 11:59:59 PM")
WScript.Echo "Parsing log folder " & strLogFolder & " for files created on " & strDate & VbCrLf & VbCrLf
' Create the recordset to hold the entire data from each file parsed
Set objData = CreateObject("ADOR.Recordset")
objData.Fields.Append "Username", adVarChar, MaxCharacters
objData.Fields.Append "DateTime", adVarChar, MaxCharacters
objData.Fields.Append "DC", adVarChar, MaxCharacters
objData.Fields.Append "PC", adVarChar, MaxCharacters
objData.Open
' Create the recordset to hold the information for each user once all of the files have been parsed
Set objUsers = CreateObject("ADOR.Recordset")
objUsers.Fields.Append "Username", adVarChar, MaxCharacters
objUsers.Fields.Append "DistinguishedName", adVarChar, MaxCharacters
objUsers.Fields.Append "ComputerName", adVarChar, MaxCharacters
objUsers.Fields.Append "LockoutCount", adDouble
objUsers.Open
For Each objFile In objFSO.GetFolder(strLogFolder).Files
If CDate(objFile.DateCreated) > dteDateFrom And CDate(objFile.DateCreated) < dteDateTo Then
WScript.Echo "Parsing file " & objFile.Name & VbCrLf & VbCrLf
Set objFile = objFSO.OpenTextFile(objFile.Path, ForReading, False)
strUsers = ";"
While Not objFile.AtEndOfStream
strLine = objFile.ReadLine
If strLine <> "" Then
arrLine = Split(LCase(strLine), ",")
objData.AddNew
objData("Username") = Trim(arrLine(0))
objData("DateTime") = Trim(arrLine(1)) & " " & Trim(arrLine(2))
objData("DC") = Trim(arrLine(3))
objData("PC") = Trim(arrLine(4))
objData.Update
If strUsers = "" Then
strUsers = arrLine(0) & ";"
Else
If InStr(strUsers, ";" & arrLine(0) & ";") = 0 Then strUsers = strUsers & arrLine(0) & ";"
End If
End If
Wend
objFile.Close
If Left(strUsers, 1) = ";" Then strUsers = Mid(strUsers, 2)
If Right(strUsers, 1) = ";" Then strUsers = Left(strUsers, Len(strUsers) - 1)
End If
Next
For Each strUser In Split(strUsers, ";")
strUserDN = Get_LDAP_User_Properties("user", "samAccountName", strUser, "distinguishedName")
objData.Filter = "Username='" & strUser & "'"
objData.MoveFirst
While Not objData.EOF
objUsers.Filter = ""
If Not objUsers.EOF Then objUsers.MoveFirst
objUsers.Filter = "Username='" & strUser & "' AND DistinguishedName='" & strUserDN & "' AND ComputerName='" & objData("PC") & "'"
If objUsers.EOF Then
objUsers.AddNew
objUsers("Username") = strUser
objUsers("DistinguishedName") = strUserDN
objUsers("ComputerName") = objData("PC")
objUsers("LockoutCount") = 1
objUsers.Update
Else
objUsers("LockoutCount") = objUsers("LockoutCount") + 1
End If
objData.MoveNext
Wend
Next
objUsers.Filter = ""
objUsers.MoveFirst
While Not objUsers.EOF
WScript.Echo objUsers("Username") & " (" & objUsers("DistinguishedName") & ") has been locked out of " & objUsers("ComputerName") & " " & objUsers("LockoutCount") & " times."
objUsers.MoveNext
Wend
Else
WScript.Echo VbCrLf & VbCrLf & "Invalid date entered. Exiting script."
End If
WScript.Echo VbCrLf & VbCrLf & "Done"
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
ASKER
Wow Rob what a nifty little script. Very cool the way it opens up and allows you to type in a date range. VERY NICE. I ran it against the ActLockout folder this morning for 5/28/2009 and appear to be getting this error:
"\\log-server\logs\scripts \lockout-t hreshold.v bs(106, 2) ADODB.Recordset: Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record."
"\\log-server\logs\scripts
Oh, on line 106 above, change this line:
objUsers.MoveFirst
to this
If Not objUsers.EOF Then objUsers.MoveFirst
Regards,
Rob.
objUsers.MoveFirst
to this
If Not objUsers.EOF Then objUsers.MoveFirst
Regards,
Rob.
ASKER
Hi Rob, yet that appeared to correct the error, it opens does it thing and then say's "done" when complete. Don't see where it wrote to though but you maybe just approaching this in steps building up to all of that or maybe perhaps I'm not looking in the right places. Looks GREAT so far!
Hmmm, OK, for a bit more output, try this....we need to see if it's populating the recordsets for you.
Regards,
Rob.
Regards,
Rob.
Set objShell = CreateObject("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
strPath = Wscript.ScriptFullName
strCommand = "%comspec% /k cscript """ & strPath & """"
objShell.Run(strCommand), 1, True
Wscript.Quit
End If
strLogFolder = "\\log-server\logs\actLockout\Logs\"
'strLogFolder = Replace(WScript.ScriptFullName, WScript.ScriptName, "")
Const ForReading = 1
Const adVarChar = 200
Const MaxCharacters = 255
Const adDouble = 5
strShortDate = objShell.RegRead("HKCU\Control Panel\International\sShortDate")
If InStr(LCase(strShortDate), "d") < InStr(LCase(strShortDate), "m") Then
strDateFormat = "dd/mm/yyyy"
Else
strDateFormat = "mm/dd/yyyy"
End If
strDate = InputBox("Please enter the date of the files that you want to search" & VbCrLf & _
"in " & strDateFormat & " format:", "Date to Search", strDateFormat)
If strDate <> "" And strDate <> strDateFormat Then
dteDateFrom = CDate(strDate & " 00:00:00 AM")
dteDateTo = CDate(strDate & " 11:59:59 PM")
WScript.Echo "Parsing log folder " & strLogFolder & " for files created on " & strDate & VbCrLf & VbCrLf
' Create the recordset to hold the entire data from each file parsed
Set objData = CreateObject("ADOR.Recordset")
objData.Fields.Append "Username", adVarChar, MaxCharacters
objData.Fields.Append "DateTime", adVarChar, MaxCharacters
objData.Fields.Append "DC", adVarChar, MaxCharacters
objData.Fields.Append "PC", adVarChar, MaxCharacters
objData.Open
' Create the recordset to hold the information for each user once all of the files have been parsed
Set objUsers = CreateObject("ADOR.Recordset")
objUsers.Fields.Append "Username", adVarChar, MaxCharacters
objUsers.Fields.Append "DistinguishedName", adVarChar, MaxCharacters
objUsers.Fields.Append "ComputerName", adVarChar, MaxCharacters
objUsers.Fields.Append "LockoutCount", adDouble
objUsers.Open
For Each objFile In objFSO.GetFolder(strLogFolder).Files
If CDate(objFile.DateCreated) > dteDateFrom And CDate(objFile.DateCreated) < dteDateTo Then
WScript.Echo "Parsing file " & objFile.Name & VbCrLf & VbCrLf
Set objFile = objFSO.OpenTextFile(objFile.Path, ForReading, False)
strUsers = ";"
While Not objFile.AtEndOfStream
strLine = objFile.ReadLine
If strLine <> "" Then
arrLine = Split(LCase(strLine), ",")
objData.AddNew
WScript.Echo "Adding " & Trim(arrLine(0)) & " from file to recordset"
objData("Username") = Trim(arrLine(0))
objData("DateTime") = Trim(arrLine(1)) & " " & Trim(arrLine(2))
objData("DC") = Trim(arrLine(3))
objData("PC") = Trim(arrLine(4))
objData.Update
If strUsers = "" Then
strUsers = arrLine(0) & ";"
Else
If InStr(strUsers, ";" & arrLine(0) & ";") = 0 Then strUsers = strUsers & arrLine(0) & ";"
End If
End If
Wend
objFile.Close
If Left(strUsers, 1) = ";" Then strUsers = Mid(strUsers, 2)
If Right(strUsers, 1) = ";" Then strUsers = Left(strUsers, Len(strUsers) - 1)
End If
Next
WScript.Echo VbCrLf & VbCrLf & "Finished reading files."
For Each strUser In Split(strUsers, ";")
strUserDN = Get_LDAP_User_Properties("user", "samAccountName", strUser, "distinguishedName")
objData.Filter = "Username='" & strUser & "'"
objData.MoveFirst
While Not objData.EOF
objUsers.Filter = ""
If Not objUsers.EOF Then objUsers.MoveFirst
objUsers.Filter = "Username='" & strUser & "' AND DistinguishedName='" & strUserDN & "' AND ComputerName='" & objData("PC") & "'"
If objUsers.EOF Then
objUsers.AddNew
WScript.Echo VbCrLf & VbCrLf & "Adding " & strUser & " to user table to count lockouts"
objUsers("Username") = strUser
objUsers("DistinguishedName") = strUserDN
objUsers("ComputerName") = objData("PC")
objUsers("LockoutCount") = 1
objUsers.Update
Else
objUsers("LockoutCount") = objUsers("LockoutCount") + 1
End If
objData.MoveNext
Wend
Next
objUsers.Filter = ""
If Not objUsers.EOF Then objUsers.MoveFirst
While Not objUsers.EOF
WScript.Echo objUsers("Username") & " (" & objUsers("DistinguishedName") & ") has been locked out of " & objUsers("ComputerName") & " " & objUsers("LockoutCount") & " times."
objUsers.MoveNext
Wend
Else
WScript.Echo VbCrLf & VbCrLf & "Invalid date entered. Exiting script."
End If
WScript.Echo VbCrLf & VbCrLf & "Done"
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
ASKER
Appears to run through script fine w/no errors. When finished it will say:
Finished Reading Files.
Done
C:\WINDOWS
Doesn't appear to write anything but then again maybe I"m not looking in the correct location.
Finished Reading Files.
Done
C:\WINDOWS
Doesn't appear to write anything but then again maybe I"m not looking in the correct location.
Hmmm, do you see output from this line:
WScript.Echo "Parsing log folder " & strLogFolder & " for files created on " & strDate & VbCrLf & VbCrLf
That folder that it referenced needs to be the name of the folder that the files exist in....
Rob.
WScript.Echo "Parsing log folder " & strLogFolder & " for files created on " & strDate & VbCrLf & VbCrLf
That folder that it referenced needs to be the name of the folder that the files exist in....
Rob.
ASKER
Yep I'll test this on Monday morning and let you know Rob. Thanks.
ASKER
I had to read what you said over a few times to make sure I was understanding it. When you said
"That folder that it referenced needs to be the name of the folder that the files exist in" I understand that statement meaning as such:
Where you reference the strLogFolder ( and in my case --->) "\\logs-server\logs\ActLoc kout\Logs"
^
(Folder it's referencing)
It appears to be referencing correctly as far as the path and folder name that the file resides in. I've double-checked it. What do you think?
"That folder that it referenced needs to be the name of the folder that the files exist in" I understand that statement meaning as such:
Where you reference the strLogFolder ( and in my case --->) "\\logs-server\logs\ActLoc
^
(Folder it's referencing)
It appears to be referencing correctly as far as the path and folder name that the file resides in. I've double-checked it. What do you think?
Sorry for the confusion, I'll try again :-)
From what I understood with the image you posted, you have
\\log-server\logs\ActLocko ut <------ FOLDER
\Logs <-----------FOLDER
DC1-100ActLockout_27.ActLo ck <-------- FILE
DC2-101ActLockout_27.ActLo ck <-------- FILE
where the FILE's are in the LOGS folder. So that's why I had
strLogFolder = "\\log-server\logs\actLock out\Logs\"
to reference the "parent" folder that the ActLock files are in. Does that make more sense?
The strLogFile needs to point to the folder that the log files are immediately contained in.
The script then goes through *every* file in that folder, processing only those that fall within the date range.
Regards,
Rob.
From what I understood with the image you posted, you have
\\log-server\logs\ActLocko
\Logs <-----------FOLDER
DC1-100ActLockout_27.ActLo
DC2-101ActLockout_27.ActLo
where the FILE's are in the LOGS folder. So that's why I had
strLogFolder = "\\log-server\logs\actLock
to reference the "parent" folder that the ActLock files are in. Does that make more sense?
The strLogFile needs to point to the folder that the log files are immediately contained in.
The script then goes through *every* file in that folder, processing only those that fall within the date range.
Regards,
Rob.
ASKER
Hmmm, strange....One thing I've noticed though...the file that called
ActLockout_5.ActLock was last modified on the 4th of May....seems a bit odd, buy in any case, you should still catch one or two files. Try specifying a date that falls in the middle of the files you have there....
Also, just out of curiosity, try the date in dd/mm/yyy order, instead of mm/dd/yyyy, just to see....
I have files that were last modified on 28th of May 2009, and this is what I get...
Regards,
Rob.
ParseFiles.jpg
ActLockout_5.ActLock was last modified on the 4th of May....seems a bit odd, buy in any case, you should still catch one or two files. Try specifying a date that falls in the middle of the files you have there....
Also, just out of curiosity, try the date in dd/mm/yyy order, instead of mm/dd/yyyy, just to see....
I have files that were last modified on 28th of May 2009, and this is what I get...
Regards,
Rob.
ParseFiles.jpg
ASKER
I'm a complete and utter dork...LOL. It was right there the whole time. In my Explorer window I have the column header set to "Date Modified" I added the column "Date Created" and got a whole shlew of different dates and when I re-ran the script usings "those" date's it populated record sets perfectly. I apologize, blonde moment there..haha.
One thing I did notice is that my "Date Created" dates are completely and totally different than my "Date Modified" dates. For example, let's say I sort the "Date Modified" column in ascending order Window (recent at top oldest at bottom) I have 6/2/2009 showing naturally, however it's "Date Created" date will say something like 08/30/2008. I'm curious, if these files just append over the top of each other? If that is the case, perhaps searching by "Date Modified" would work out better? What do you think?
One thing I did notice is that my "Date Created" dates are completely and totally different than my "Date Modified" dates. For example, let's say I sort the "Date Modified" column in ascending order Window (recent at top oldest at bottom) I have 6/2/2009 showing naturally, however it's "Date Created" date will say something like 08/30/2008. I'm curious, if these files just append over the top of each other? If that is the case, perhaps searching by "Date Modified" would work out better? What do you think?
ASKER
I fixed it Rob ( :
Changed this to read:
If CDate(objFile.DateLastModi fied) > dteDateFrom And CDate(objFile.DateLastModi fied) < dteDateTo Then
WScript.Echo "Parsing file " & objFile.Name & VbCrLf & VbCrL
it populates and goes through all record sets fine. I suppose the last thing we can do now is add the email functionality upon detection of any anomalies then we are DONE.. wooohooo!
Changed this to read:
If CDate(objFile.DateLastModi
WScript.Echo "Parsing file " & objFile.Name & VbCrLf & VbCrL
it populates and goes through all record sets fine. I suppose the last thing we can do now is add the email functionality upon detection of any anomalies then we are DONE.. wooohooo!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oh, I left my test lines in again. Please change this:
'strLogFolder = "\\log-server\logs\actLock out\Logs\"
strLogFolder = Replace(WScript.ScriptFull Name, WScript.ScriptName, "")
to this
strLogFolder = "\\log-server\logs\actLock out\Logs\"
Regards,
Rob.
'strLogFolder = "\\log-server\logs\actLock
strLogFolder = Replace(WScript.ScriptFull
to this
strLogFolder = "\\log-server\logs\actLock
Regards,
Rob.
ASKER
Rob I think this did it man, AWESOME JOB as usual man! I really hope your being rewarded a little more besides points by EE. Thanks a million man!
ASKER
Everytime Rob enlists his skill's and knowledge into my projects, I get this warm and fuzzy feeling of comfort. GREAT JOB!
>> I really hope your being rewarded a little more besides points by EE
I wish! Well I have had a few job offers, but I can't take them up just yet...things are too busy for me....but I'm learning all the time, so that's good enough for me! I still get to impress my boss with the things I can do with making our IT Administration easier!
Thanks for the grade....onto the next one! :-)
I wish! Well I have had a few job offers, but I can't take them up just yet...things are too busy for me....but I'm learning all the time, so that's good enough for me! I still get to impress my boss with the things I can do with making our IT Administration easier!
Thanks for the grade....onto the next one! :-)
How Can I Retrieve Just Audit Failures, Warnings, and Errors from My Event Logs?
http://www.microsoft.com/technet/scriptcenter/resources/qanda/sept05/hey0913.mspx
Where you can also specify a time range to query using the TimeWritten property.
You could just search for the relevant event ids, then read the other attributes to determine what happened.
If you post a sample event of an account lockout, we can modify that code to suit.
Regards,
Rob.