Hedef Gruplar: Administrators, Domain Admins, Account Operators, Organization Management, Enterprise Admins, Group Policy Creator Owners, Protected Users, ve Schema Admins gibi önemli grupları hedef alır.
Değişiklik İzleme: Grup üyeliğindeki eklemeleri ve çıkarmaları tespit eder. Her değişiklik, kullanıcı, grup ve değişiklik tipi bilgileri ile detaylandırılır.
HTML Raporlama: Mevcut grup üyeliklerini ve yapılan değişiklikleri içeren detaylı bir HTML e-posta raporu hazırlar.
Otomatik E-posta Gönderimi: E-posta ile bildirim gönderilmesi gereken durumları algılar ve uygun recipient'lere bildirir.
# =============================================================================
# Script Name: Send-ADGroupChangeAlert.ps1
# Author: Elif Uçhan
# Date: 2024-05-22
# LastUpdate: 2024-09-11
# Description: This script detects Active Directory group membership changes
# =============================================================================
Clear-Host
# ========================
# Collection Data Section
# ========================
Function EventID-To-HTML($ComputerName = $env:COMPUTERNAME)
{
# Define the target groups
$targetGroups = @(
"Administrators",
"Domain Admins",
"Account Operators"
"Organization Management",
"Enterprise Admins",
"Group Policy Creator Owners",
"Protected Users",
"Schema Admins"
)
# Initialize HTML content
$htmlContent = ""
$htmlMemberships = "" # Track current memberships
$sendEmail = $false # Flag to check if we need to send an email
# Initialize a list to store detailed changes
$detailedChanges = @()
# Iterate through the target groups
foreach ($group in $targetGroups) {
# Define the path to store previous group members
$filePath = "$env:TEMP$group-Members.txt"
# Get current members of the group
$currentMembers = Get-ADGroupMember -Identity $group | Where-Object { $_.ObjectClass -eq "User" } | Select-Object -ExpandProperty SamAccountName
# Ensure $currentMembers is not null
if (-not $currentMembers) {
$currentMembers = @() # Initialize to an empty array if no members found
}
# Get previous members from a file (or create the file if it doesn't exist)
if (Test-Path $filePath) {
$previousMembers = Get-Content -Path $filePath
} else {
$previousMembers = @() # Initialize to an empty array if the file doesn't exist
}
# Ensure $previousMembers is not $null
if (-not $previousMembers) {
$previousMembers = @() # Initialize to an empty array if null
}
# Compare current members to previous members to detect additions and deletions
$membersAdded = Compare-Object -ReferenceObject $previousMembers -DifferenceObject $currentMembers -PassThru | Where-Object { $_ -in $currentMembers }
$membersRemoved = Compare-Object -ReferenceObject $previousMembers -DifferenceObject $currentMembers -PassThru | Where-Object { $_ -in $previousMembers }
# If members were added to the group
if ($membersAdded.Count -gt 0) {
$sendEmail = $true # Set the flag to send email
foreach ($member in $membersAdded) {
$detailedChanges += [pscustomobject]@{
User = $member
Group = $group
ChangeType = "Eklenen"
}
}
}
# If members were removed from the group
if ($membersRemoved.Count -gt 0) {
$sendEmail = $true # Set the flag to send email
foreach ($member in $membersRemoved) {
$detailedChanges += [pscustomobject]@{
User = $member
Group = $group
ChangeType = "Kaldırılan"
}
}
}
# Save current members to the file for future comparison
$currentMembers | Out-File -FilePath $filePath -Force
}
# Construct HTML content for current group memberships
foreach ($group in $targetGroups) {
$currentMembers = Get-ADGroupMember -Identity $group | Where-Object { $_.ObjectClass -eq "User" } | Select-Object -ExpandProperty SamAccountName
if ($currentMembers.Count -gt 0) {
$htmlMemberships += @"
<p><b><span style='color:blue'>$group</span> grubunun mevcut üyeleri:</b></p>
<table border='1' style='width:100%; border-collapse:collapse;'>
<tr>
<th style='background-color:#5bc0de; color:#fff;'>Kullanıcı</th>
</tr>
"@
foreach ($member in $currentMembers) {
$htmlMemberships += "<tr><td>$member</td></tr>"
}
$htmlMemberships += "</table>"
}
}
# If detailed changes exist, format them in a table
if ($detailedChanges.Count -gt 0) {
$htmlContent += @"
<p><b>Yapılan Değişiklikler:</b></p>
<table border='1' style='width:100%; border-collapse:collapse;'>
<tr>
<th style='background-color:#d9534f; color:#fff;'>Kullanıcı</th>
<th style='background-color:#d9534f; color:#fff;'>Grup</th>
<th style='background-color:#d9534f; color:#fff;'>Değişiklik Tipi</th>
</tr>
"@
foreach ($change in $detailedChanges) {
$htmlContent += "<tr><td>$($change.User)</td><td>$($change.Group)</td><td>$($change.ChangeType)</td></tr>"
}
$htmlContent += "</table>"
} else {
$htmlContent = "<p><b>Hedef gruplarda değişiklik yok.</b></p>"
}
# Construct HTML start code
$htmlStart = @"
<html>
<head>
<style>
body {
background-color: #5a666b;
font-family: Arial, sans-serif;
color: #333;
margin: 0;
padding: 0;
}
.container {
width: 80%;
margin: 20px auto;
}
h2 {
color: #c1dae6;
}
p {
margin-bottom: 10px;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.alert {
background-color: #f8d7da;
border-color: #f5c6cb;
color: #721c24;
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: .25rem;
}
.alert-danger {
background-color: #f8d7da;
border-color: #f5c6cb;
color: #721c24;
}
.alert-danger h2 {
color: #721c24;
}
table {
border: 1px solid #ddd;
border-collapse: collapse;
width: 100%;
margin-bottom: 20px;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #5bc0de;
color: white;
}
</style>
</head>
<body>
<div class='container'>
<h2><b>Sistem Güvenlik Uyarısı: <span style='font-style:normal; color:Blue'>Grup Üyeliği Değişikliği</span></b></h2>
<p><b>Olay Gerçekleştiği Tarih: <span style='font-style:italic; color:Blue'>$(Get-Date) - $ComputerName</span></b></p>
$htmlContent
$htmlMemberships
<br><i><span style='color:red'>Bu rapor otomatik olarak oluşturulmuştur.</span> <br><span>Yanıt vermeyin. Rapor Sorumlusu: BT Ekibi</span></i>
</div>
</body>
</html>
"@
return $htmlStart, $sendEmail
}
# ======================
# Sending Email Section
# ======================
# Define email parameters
$strFrom = "alert@domain.com"
$strTo = "exadmin@test.local"
$strSubject = "*** Active Directory Grup Üyeliği Değişikliği ***"
$strSMTPServer = "exch.TEST.local"
# Generate HTML body and check if we need to send email
$htmlBody, $sendEmail = EventID-To-HTML
# If changes were detected, send an email
if ($sendEmail) {
try {
# Create email message
$mailMessage = New-Object system.net.mail.mailmessage
$mailMessage.from = $strFrom
$mailMessage.To.Add($strTo)
$mailMessage.Subject = $strSubject
$mailMessage.Body = $htmlBody
$mailMessage.IsBodyHtml = $true
# Create SMTP client
$smtpClient = New-Object Net.Mail.SmtpClient($strSMTPServer)
$smtpClient.Send($mailMessage)
Write-Output "E-posta başarıyla gönderildi."
} catch {
Write-Output "E-posta gönderilirken bir hata oluştu: $_"
}
} else {
Write-Output "Değişiklik tespit edilmedi. E-posta gönderilmedi."
}
