Powershell : Distribution Group Modifications (with Report)


This is quite a simple script that will look for a defined distribution group name, and then look for all the valid events on all your domain controllers to see who was added that user to that group.

Simply put we are looking for Event ID 4728 – "A member was added to a security-enabled global group" however, we are not interested in every single event because that could be quite an extensive list.

We only need to know about events that match the distribution group name, this would also reveal the perpetrator that added users to this group, can you speak to example we are looking for a distribution group called “Honeypot”

Script : GroupModificationFinder.ps1

# Define output CSV file path with timestamp
$Timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$CsvFile = "GroupMembershipChanges_$Timestamp.csv"

# Define the target group name
$TargetGroupName = "Honeypot"

# Get all domain controllers
$DomainControllers = Get-ADDomainController -Filter * | Select-Object -ExpandProperty HostName

# Initialize an array to store results
$Results = @()

# Iterate over each domain controller
foreach ($DC in $DomainControllers) {
    Write-Host "Searching on: $DC"

    try {
        # Query events directly using Get-WinEvent with ComputerName parameter
        $Events = Get-WinEvent -ComputerName $DC -FilterHashtable @{
            LogName = 'Security'
            ID = @(4746, 4728, 4732, 4733)
            StartTime = (Get-Date).AddDays(-90)
        } -ErrorAction Stop | 
        Where-Object {
            $_.Properties | 
            ForEach-Object { $_.Value } | 
            Where-Object { $_ -match [regex]::Escape($TargetGroupName) }
        }

        if ($Events) {
            foreach ($Event in $Events) {
                $EventDetails = @{
                    TimeCreated = $Event.TimeCreated
                    DomainController = $DC
                    EventID = $Event.Id
                    GroupName = $TargetGroupName
                    Message = $Event.Message -replace "`r`n", " "  # Flatten message
                }
                $Results += New-Object PSObject -Property $EventDetails
            }
            Write-Host "Found $($Events.Count) events on $DC"
        }
    } catch {
        Write-Host "Error retrieving logs from $DC - $_"
    }
}

# Export structured data to CSV if there are results
if ($Results) {
    $Results | Export-Csv -Path $CsvFile -NoTypeInformation -Encoding UTF8
    Write-Host "Results saved to CSV: $CsvFile"
} else {
    Write-Host "No matching events found across all domain controllers."
}
Previous Post Next Post

نموذج الاتصال