Jump to content

List all users in AD


Recommended Posts

In your query you can use the following to only show enabled accounts:

(!userAccountControl:1.2.840.113556.1.4.803:=2)

You can use the whenCreated to get the account creation time, you can use StringFormat or as in the example below, use Melba23 Date_Time_Convert udf (see code below for download url) to convert the whenCreated into a readable format that can be used with _DateDiff to determine the date difference.

#include <AD.au3>
;~ Download Melba23 Date_Time_Convert <DTC.au3> UDF from https://www.autoitscript.com/forum/topic/154684-date_time_convert-bugfix-version-27-may-15/
#include <DTC.au3>
#include <File.au3>

_GetUsers()

Func _GetUsers()
    ; Open Connection to the Active Directory.
    _AD_Open()
    If @error Then Exit MsgBox(16, "Active Directory Error", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @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,whenCreated")
    ;~ Insert another column for date difference
    _ArrayColInsert($aUserObjects, 3)

    ;~ To delete an array item (removing accounts that are less than 90 days), you need to reverse the loop
    For $i = UBound($aUserObjects) - 1 To 1 Step - 1
        ;~ Convert accountExpires to readable date/time
        If IsObj($aUserObjects[$i][1]) Then $aUserObjects[$i][1] = _GetADDateTime($aUserObjects[$i][1], 1)
        If $aUserObjects[$i][2] <> "" Then
            ;~ Convert whenCreated to readable date/time (required for _DateDiff function
            $aUserObjects[$i][2] = _Date_Time_Convert($aUserObjects[$i][2], "yyyyMMddHHmmss", "yyyy/MM/dd HH:mm:ss")
            ;~ Get date difference in days between whenCreated and accountExpires
            If $aUserObjects[$i][1] <> "n/a" Then
                $aUserObjects[$i][3] = _DateDiff("D", $aUserObjects[$i][2], $aUserObjects[$i][1])
                ;~ If the date difference is less than 90 days then remove from the array
                If $aUserObjects[$i][3] < 90 Then _ArrayDelete($aUserObjects, $i)
            EndIf
        EndIf
    Next

    _ArrayDisplay($aUserObjects)

    _AD_Close()

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

 

Link to comment
Share on other sites

  • 3 months later...
  • Replies 48
  • Created
  • Last Reply

Top Posters In This Topic

On 6/27/2022 at 7:46 PM, Subz said:

In your query you can use the following to only show enabled accounts:

(!userAccountControl:1.2.840.113556.1.4.803:=2)

You can use the whenCreated to get the account creation time, you can use StringFormat or as in the example below, use Melba23 Date_Time_Convert udf (see code below for download url) to convert the whenCreated into a readable format that can be used with _DateDiff to determine the date difference.

#include <AD.au3>
;~ Download Melba23 Date_Time_Convert <DTC.au3> UDF from https://www.autoitscript.com/forum/topic/154684-date_time_convert-bugfix-version-27-may-15/
#include <DTC.au3>
#include <File.au3>

_GetUsers()

Func _GetUsers()
    ; Open Connection to the Active Directory.
    _AD_Open()
    If @error Then Exit MsgBox(16, "Active Directory Error", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @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,whenCreated")
    ;~ Insert another column for date difference
    _ArrayColInsert($aUserObjects, 3)

    ;~ To delete an array item (removing accounts that are less than 90 days), you need to reverse the loop
    For $i = UBound($aUserObjects) - 1 To 1 Step - 1
        ;~ Convert accountExpires to readable date/time
        If IsObj($aUserObjects[$i][1]) Then $aUserObjects[$i][1] = _GetADDateTime($aUserObjects[$i][1], 1)
        If $aUserObjects[$i][2] <> "" Then
            ;~ Convert whenCreated to readable date/time (required for _DateDiff function
            $aUserObjects[$i][2] = _Date_Time_Convert($aUserObjects[$i][2], "yyyyMMddHHmmss", "yyyy/MM/dd HH:mm:ss")
            ;~ Get date difference in days between whenCreated and accountExpires
            If $aUserObjects[$i][1] <> "n/a" Then
                $aUserObjects[$i][3] = _DateDiff("D", $aUserObjects[$i][2], $aUserObjects[$i][1])
                ;~ If the date difference is less than 90 days then remove from the array
                If $aUserObjects[$i][3] < 90 Then _ArrayDelete($aUserObjects, $i)
            EndIf
        EndIf
    Next

    _ArrayDisplay($aUserObjects)

    _AD_Close()

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

 

Hello @Subzjust starting to work on this script again.  Can you explain to me what this is doing?

(!userAccountControl:1.2.840.113556.1.4.803:=2)
Link to comment
Share on other sites

my ultimate goal for this script is to

1) search all accounts in AD that are contractors

2) check if the contractors accounts have a expire date less than 90 days

3) create a list of contractor accounts that have either no expire date and/or more than 90 days expire date set

4) send list as attachment via email

Link to comment
Share on other sites

  • userAccountControl = LDAP Name
  • 1.2.840.113556.1.4.803 = LDAP matching rule bit and
  • 2 = Disabled account
  • ! = Logical Not Operator

Disabled User Accounts = userAccountControl:1.2.840.113556.1.4.803:=2
Enabled User Accounts = !userAccountControl:1.2.840.113556.1.4.803:=2

 

Link to comment
Share on other sites

  • 1 month later...

Unable to test, but something like below should work.

$aUserObjects[$i][3] = _DateDiff("D", $aUserObjects[$i][2], $aUserObjects[$i][1])
                ;~ If the date difference is less than 90 days then remove from the array
                If $aUserObjects[$i][3] < 90 Then _ArrayDelete($aUserObjects, $i)

change to

$aUserObjects[$i][3] = _DateDiff("D", $aUserObjects[$i][1], _NowCalc())
                ;~ If the date difference is more than 90 days then remove from the array
                If $aUserObjects[$i][3] > 90 Then _ArrayDelete($aUserObjects, $i)
Link to comment
Share on other sites

Thanks @Subzbut to clean it up can we removed the "whenCreated" attribute?  We don't need to collect that data.

Just looking for if the contractors expire date is more that 90 days from today (that time the script is being ran).

I think the changes you made above worked but it returned more account's than I was expecting so I am still testing it.

Link to comment
Share on other sites

You just remove the property from the search

    $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")

 

Link to comment
Share on other sites

  • 2 months later...

Hello all.

Looking into this once again.

So again I'm just trying to query AD for user accounts with the "description" attribute that contains "contractor" or "consultants" and if they have NO expire date then show me in a list or something that I then want to send a report in a email.

I'm stuck on going through the array and checking if the expire data is NOT = "0" which means it has no expire data and removing from the array and ultimately showing me just accounts with no expire date.

 

#include <AD.au3>

_GetUsers()

Func _GetUsers()
    _AD_Open()
        If @error Then Exit MsgBox(16, "Active Directory Error", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @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")
    For $i = 0 To UBound($aUserObjects) - 1
        If IsObj($aUserObjects[$i][1]) Then $aUserObjects[$i][1] = _GetADDateTime($aUserObjects[$i][1], 1)
            If Not $aUserObjects[$i][1] = 0 Then
                _ArrayDelete($aUserObjects, $aUserObjects[$i])
            EndIf
    Next

    _ArrayDisplay($aUserObjects)

    _AD_Close()

EndFunc   ;==>_GetUsers

 

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...