Script Repository


User accounts created and/or disabled during a certain number of days

February 22, 2021
1800

The script creates and emails a CSV report on users created and disabled during a certain number of days.

To schedule such a report, create a scheduled task configured for the Domain-DNS object type that runs the script and assign it over any of your AD domains. To add the script to a scheduled task, use the Run a program or PowerShell script action.

Parameters:

  • $days - Specifies the number of days to include in the report.
  • $propertiesToExport - Specifies a list of properties that will be included in the report for each user.
  • $csvFilePath - Specifies a UNC path to the CSV file that will be created by the script.
  • $removeCSVFile - Specifies whether to remove the CSV file after it is sent.
  • $to - Specifies a comma separated list of recipients of the report.
  • $subject - Specifies the email message subject.
  • $message - Specifies the email notification message.
  • $from - Specifies the e-mail address from which the message will be sent.
  • $smtpServer - Specifies the SMTP server to use when sending a notification.
Edit Remove
PowerShell
$days = 30 # TODO: modify me
$propertiesToExport = @(
    @("name", "Name"),
    @("distinguishedName", "Parent OU"),
    @("description", "Description"),
    @("department", "Department"),
    @("division", "Division"),
    @("mail", "Email"),
    @("givenName", "First Name"),
    @("sn", "Last Name"),
    @("sAMAccountName", "Logon Name"),
    @("manager", "Manager"),
    @("physicalDeliveryOfficeName", "Office"),
    @("title", "Job Title"),
    @("lastLogonTimestamp", "Last Logon"),
    @("employeeID", "Employee ID"),
    @("userAccountControl", "Account Options")
) # TODO: modify me

# CSV file settings
$csvFilePath = "C:\scripts\report.csv" # TODO: modify me
$removeCSVFile = $True # TODO: modify me

# E-mail settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "Monthly Report for Created and Disabled Accounts" # TODO: modify me
$message = "Monthly Report for Created and Disabled Accounts" # TODO: modify me
$from = "noreply@domain.com" # TODO: modify me
$smtpServer = "mail.domain.com" # TODO: modify me

$accountOptions = @{
    1 = "Logon script is executed";
    2 = "Account is disabled";
    8 = "Home directory is required";
    16 = "Account is locked out";
    32 = "No password is required";
    64 = "User cannot change password";
    128 = "Store password using reversible encryption";
    256 = "Temporary duplicated account";
    512 = "Normal account";
    2048 = "Interdomain trust account";
    4096 = "Workstation trust account";
    8192 = "Server trust account";
    65536 = "Password never expires";
    131072 = "MNS logon account";
    262144 = "Smart card is required for interactive logon";
    524288 = "Account is trusted for delegation";
    1048576 = "Account is sensitive and cannot be delegated";
    2097152 = "Use Kerberos DES encryption types for this account";
    4194304 = "Do not require Kerberos preauthentication";
    8388608 = "Password has expired";
    16777216 = "Account is trusted to authenticate for delegation"
}

function GetObjectDisplayName($objectDN)
{
    $objectPath = New-Object -TypeName "Softerra.Adaxes.Adsi.AdsPath" -ArgumentList @($null, $objectDN)
    return [Softerra.Adaxes.Utils.ObjectNameHelper]::GetObjectName($objectPath, "IncludeParentPath")
}

function BuildReport($searFilter, $propertiesToExport, $action)
{
    # Get display names for the properties
    $propertyLdapNames = @()
    $propertiesFriendlyNames = @()
    foreach ($propertyInfo in $propertiesToExport)
    {
        $propertyLdapNames += $propertyInfo[0]
        $propertiesFriendlyNames += $propertyInfo[1]
    }
    
    # Find users
    $searcher = $Context.BindToObject("Adaxes://rootDSE")
    $searcher.SearchFilter = $searFilter
    $searcher.PageSize = 500
    $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.SetPropertiesToLoad($propertyLdapNames)
    $searcher.VirtualRoot = $True
    
    try
    {
        $searchResultIterator = $searcher.ExecuteSearch()
        $searchResults = $searchResultIterator.FetchAll()
        
        # Build report
        $report = @()
        foreach ($searchResult in $searchResults)
        {                        
            # Get property values for each user
            $record = New-Object PSObject
            $record | Add-Member -MemberType NoteProperty -Name "Action" -Value $action
            for ($i = 0; $i -lt $propertyLdapNames.Length; $i++)
            {
                $propertyName = $propertyLdapNames[$i]
                
                # Get property value
                $value = $searchResult.Properties[$propertyName].Value
                switch ($propertyName)
                {
                    "distinguishedName"
                    {
                        # Get parent object display name
                        $userDN = New-Object "Softerra.Adaxes.Ldap.DN" $value
                        $value = GetObjectDisplayName $userDN.Parent
                    }
                    "manager"
                    {
                        # Get manager display name
                        if ($value -ne $NULL)
                        {
                            $value = GetObjectDisplayName $managerDN
                        }
                    }
                    "lastLogonTimestamp"
                    {
                        if (($value -eq 0) -or ($value -eq $NULL))
                        {
                            $value = "unspecified"
                        }
                        else
                        {
                            try
                            {
                                $value = [DateTime]::FromFiletime([Int64]::Parse($value))
                            }
                            catch
                            {
                                $Context.LogMessage("Cannot convert value '$value' to the date/time format", "Warning") # TODO: modify me
                                $value = "unspecified"
                            }
                        }
                    }
                    "userAccountControl"
                    {
                        $userAccountControl = @()
                        foreach ($key in $accountOptions.Keys)
                        {
                            if ($value -band $key)
                            {
                                $userAccountControl += $accountOptions[$key]
                            }
                        }
                        $value = $userAccountControl -join ";"
                    }
                }
                
                $record | Add-Member -MemberType NoteProperty -Name $propertiesFriendlyNames[$i] -Value $value
            }
            $report += $record
        }
        return ,$report
    }
    finally
    {
        # Release resources used by the search
        $searchResultIterator.Dispose()
    }
}

# Build CSV report

# Add users created during the time term to the report
$csvReport = @()

if ($days -ne 0)
{
   $startDate = (Get-Date).AddDays(-$days)
   $dateGenerilized = [Softerra.Adaxes.Utils.Transform]::ToGeneralizedTime($startDate.ToUniversalTime())
   $filter = "(&(sAMAccountType=805306368)(whenCreated>=$dateGenerilized))"
}
else
{
    $filter = "(sAMAccountType=805306368)"
}

$csvReport += BuildReport $filter $propertiesToExport "Created"

# Get GUIDs of all users that were disabled during the period from Adaxes log

# Bind to the directory object representing the General Log
$path = $Context.GetWellKnownContainerPath("ServiceLog")
$serviceLog = $Context.BindToObject($path)

$generalLog = $serviceLog.GeneralLog
if ($days -ne 0)
{
   $generalLog.StartDateTime = $startDate
   $generalLog.EndDateTime = Get-Date
}

# Get the log records
$log = $generalLog.Log
$records = $log.GetPage(0)

# Build filter to search for disabled users
$filterParts = New-Object "System.Text.StringBuilder"
foreach ($record in $records)
{
    if (($record.TargetObjectType -ne "user") -or ($record.TargetObjectGuid -eq $NULL))
    {
        continue
    }
    
    $operationTypes = $record.GetOperationTypes()
    if ($operationTypes -notcontains "disable account")
    {
        continue
    }
    
    $filterPart = [Softerra.Adaxes.Ldap.FilterBuilder]::Create("ObjectGuid", [Guid]$record.TargetObjectGuid)
    [void]$filterParts.Append($filterPart)
}

if ($filterParts.Length -ne 0)
{
    $filter = New-Object "System.Text.StringBuilder"
    [void]$filter.Append("(&(userAccountControl:1.2.840.113556.1.4.803:=2)(|")
    [void]$filter.Append($filterParts)
    [void]$filter.Append("))")
    
    # Add disabled users to the report
    $csvReport += BuildReport $filter.ToString() $propertiesToExport "Disabled"
}

# Send mail
$csvReport | Sort-Object -Property Action, Name | Export-csv -NoTypeInformation -Path $csvFilePath
Send-MailMessage -To $to -from $from -SmtpServer $smtpServer -Subject $subject -Body $message -Attachments $csvFilePath

if ($removeCSVFile)
{
    # Remove temporary file
    Remove-Item $csvFilePath -Force
}

Comments ( 0 )
No results found.
Leave a comment