Jump to content

Help Improving Script


 Share

Recommended Posts

Hi

I have a script that was piecemealed together and is working but I know it can be better.  I'm looking for some help on improving it while helping add one additional functionality to it.

This script will check all user objects in AD that are none-FTE (contractors/consultants) and check if they have NO expire date, send this to an array, convert the array to a string and email the results.  This is working but the email is not formatted in a nice way like I would prefer.

The added functionality that I would like to add is to check if these accounts do have a expire date GREATER than 30 days and if so then add them to the array and email also in the same report.

I'm also going to implement this UDF so I can email the list to more than one user:

#include <AD.au3>
#include <AD.au3>
#include <File.au3>
#include <Inet.au3>
#include <Date.au3>


Global $logFile = @ScriptDir & "\non-FTE out of compliance log.log", $hFile = FileOpen($logFile, 1)

_GetUsers()

Func _GetUsers()

    _FileWriteLog($hFile, "Started")

    _AD_Open()
        If @error Then Exit _FileWriteLog($hFile, "Active Directory Error. Function _AD_Open encountered a problem. Error: " & @error & " extended error: " & @extended)

    ; Search all of AD for contractors and exclude _DT accounts.
    $aUserObjects = _AD_GetObjectsInOU("", "(&(objectcategory=person)(objectclass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(!(sAMAccountName=*_dt)(|(title=*contractor*)(title=*consultant*)(description=*contractor*)(description=*consultant*))))", 2, "sAMAccountName,accountExpires,Name")

     For $i = 0 To UBound($aUserObjects) -1
        If IsObj($aUserObjects[$i][1]) Then $aUserObjects[$i][1] = _GetADDateTime($aUserObjects[$i][1], 1)
     Next

    ;Debug
    ;_ArrayDisplay($aUserObjects, "All contractors")

    Local $NewArray[1][2]

    For $x = 0 to UBound($aUserObjects) -1
        If $aUserObjects[$x][1] = 0  Then
            _ArrayAdd($NewArray, $aUserObjects[$x][0])
            _ArrayAdd($NewArray, $aUserObjects[$x][2])
        EndIf
    Next

    ;Debug
    ;_ArrayDisplay($NewArray)

    _AD_Close()

    ;Convert array to string so I can email
    Global $BadUsers = _ArrayToString($NewArray, " ")

    ;Email list of out of compliance users
    _SendEmail($BadUsers)

EndFunc   ;==>_GetUsers


Func _GetADDateTime($_oADObject, $_iFlag = 0)
    Local $sAD_DTStruct, $sTemp3
    If $_iFlag = 1 Then
        If $_oADObject.LowPart = -1 Then Return 0
        If $_oADObject.LowPart > 0 And $_oADObject.HighPart > 0 Then
            $sAD_DTStruct = DllStructCreate("dword low;dword high")
            DllStructSetData($sAD_DTStruct, "Low", $_oADObject.LowPart)
            DllStructSetData($sAD_DTStruct, "High", $_oADObject.HighPart)
            $sAD_Temp = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sAD_DTStruct))
            $sTemp3 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sAD_Temp))
            Return _Date_Time_SystemTimeToDateTimeStr($sTemp3, 1)
        EndIf
    EndIf
 ; Convert IADsLargeInteger parts to 100ns count
 $iLowPart = $_oADObject.LowPart
 $iHighPart = $_oADObject.HighPart
 If $iLowPart < 0 Then $iHighPart += 1; Compensate for IADsLargeInteger interface error
 $iDateParts= $iHighPart * 2 ^ 32
 $iDateParts+= $iLowPart

 ; Check if user ever logged in
 If $iDateParts= 0 Then
    Return "n/a"
 Else
 ; Convert 100ns count to integer seconds
 $iSeconds = Floor($iDateParts/ 10000000)

 ; Convert seconds since 12:00AM January 01, 1601 to date string
 $sDateTime = _DateAdd("S", $iSeconds, "1601/01/01 00:00:00")

 ; Display result
 Return $sDateTime
 EndIf
EndFunc


Func _SendEmail($List)

Local $s_SmtpServer = "removed"
Local $s_FromName = "removed"
Local $s_FromAddress = "removed"
Local $s_ToAddress = "removed"
Local $s_Subject = "test report"
Local $as_Body[3]
$as_Body[0] = "Here is a list of contractor out of compliance."
$as_Body[1] = $List
$as_Body[2] = @CRLF & @CRLF & @CRLF & @CRLF & @CRLF & @CRLF & "Report created on: " & _NowDate() & " " & _NowTime() & " " & "on server: " & @ComputerName
Local $iResponse = _INetSmtpMail($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject, $as_Body)
Local $iErr = @error
If $iResponse = 1 Then
    _FileWriteLog($hFile, "List: " & $List)
    _FileWriteLog($hFile, "Mail sent")
Else
    _FileWriteLog($hFile, "Error! " & "Mail failed with error code " & @error & "extended error: " & @extended)
EndIf

EndFunc

 

Link to comment
Share on other sites

I have no idea what your data looks like, maybe you can provide an example of the data that you're emailing, or what the array looks like, with any personal information removed?

Otherwise, I would recommend looping over the array yourself and using something like StringFormat to format the data nicely:

#include <Date.au3>
#include <Array.au3>

Global Enum $eUser_Name, $eUser_Date, $eUser_Hours, $eUser_Max
Global $aUsers[][$eUser_Max] = [ _
        ['John', _DateAdd('D', Random(-100, -1, 1), _NowCalc()), Random(32, 48, 1)], _
        ['Sally', _DateAdd('D', Random(-100, -1, 1), _NowCalc()), Random(32, 48, 1)], _
        ['antmar904', _DateAdd('D', Random(-1, -1, 1), _NowCalc()), Random(32, 48, 1)], _
        ['Zach', _DateAdd('D', Random(-100, -1, 1), _NowCalc()), Random(32, 48, 1)], _
        ['Alex', _DateAdd('D', Random(-100, -1, 1), _NowCalc()), Random(32, 48, 1)] _
        ]

;~ _ArrayDisplay($aUsers)

Global $sUnformatted = _ArrayToString($aUsers, ' ')
ConsoleWrite('_ArrayToString formatted output: ' & @CRLF & $sUnformatted & @CRLF & @CRLF)

Global $sFormatted = 'Formatted data output: ' & @CRLF & _
        '-            Name            |           Last worked            |    Hours ' & @CRLF
For $iUser = 0 To UBound($aUsers) - 1
    $sFormatted &= StringFormat('- Name: %20s | Last worked: %19s | Hours: %3.2f', _
            $aUsers[$iUser][$eUser_Name], _
            $aUsers[$iUser][$eUser_Date], _
            $aUsers[$iUser][$eUser_Hours]) & _
            @CRLF
Next
ConsoleWrite($sFormatted & @CRLF)

The output looks like this:

_ArrayToString formatted output: 
John 2022/12/27 11:22:43 34
Sally 2023/01/27 11:22:43 38
antmar904 2023/02/18 11:22:43 47
Zach 2023/02/07 11:22:43 40
Alex 2023/01/11 11:22:43 46

Formatted data output: 
-            Name            |           Last worked            |    Hours 
- Name:                 John | Last worked: 2022/12/27 11:22:43 | Hours: 34.00
- Name:                Sally | Last worked: 2023/01/27 11:22:43 | Hours: 38.00
- Name:            antmar904 | Last worked: 2023/02/18 11:22:43 | Hours: 47.00
- Name:                 Zach | Last worked: 2023/02/07 11:22:43 | Hours: 40.00
- Name:                 Alex | Last worked: 2023/01/11 11:22:43 | Hours: 46.00

 

We ought not to misbehave, but we should look as though we could.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...