The script will generate and send a CSV report to notify owners of groups with information on users who are members of the groups they own.
To generate the reports upon request, you can create a custom command that runs the script. To schedule the reports, you need to create a scheduled task configured for the Domain-DNS object type and run it against any of your AD domains.
To add the script to a custom command or scheduled task, use the Run a program or PowerShell script action.
Parameters:
- $csvFilePath - Specifies the path to the CSV file that will be created by the script.
- $attributesToExport - Specifies a list of AD attributes of the users to export.
- $from - Specifies the email address from which the notification will be sent.
- $smtpServer - Specifies the SMTP Server to user for sending the report.
- $subject - Specifies the notification message subject.
- $messageBody - Specifies the text for the notification message body.
PowerShell
$csvFilePath = "C:\temp\report.csv" # TODO: modify me
$attributesToExport = @("name", "mail") # TODO: modify me
# Email message settings
$from = "noreply@domain.com" # TODO: modify me
$smtpServer = "mail.domain.com" # TODO: modify me
$subject = "My Subject" # TODO: modify me
$messageBody = "List of users in the groups you own" # TODO: modify me
function CreateCsvFile($groupPath, $attributesToExport, $csvFilePath)
{
# Build filter to find all users who are members of the specified group
$searcher = $Context.BindToObject("Adaxes://rootDSE")
$filter = New-Object "System.Text.StringBuilder"
$filter.Append("(&(sAMAccountType=805306368)(|") | Out-Null
foreach ($path in $groupPath)
{
$group = $Context.BindToObject($path)
foreach ($memberGuidBytes in $group.GetEx("adm-MembersGuid"))
{
# Add the user's GUID to the filter
$filterPart = [Softerra.Adaxes.Ldap.FilterBuilder]::Create($memberGuidBytes)
$filter.Append($filterPart) | Out-Null
}
}
$filter.Append("))") | Out-Null
# Search users
$searcher.SearchFilter = $filter.ToString()
$searcher.PageSize = 500
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.SetPropertiesToLoad($attributesToExport)
$searcher.VirtualRoot = $True
try
{
$searchResult = $searcher.ExecuteSearch()
$users = $searchResult.FetchAll()
if ($users.Count -eq 0)
{
# No users in groups
return $False
}
#
$rows = @()
foreach ($user in $users)
{
$reportEntry = New-Object PSObject
foreach ($attributeName in $attributesToExport)
{
$value = $user.Properties[$attributeName].Value
$reportEntry | Add-Member -Name "$attributeName" -Value $value -MemberType NoteProperty
}
$rows += $reportEntry
}
# Create CSV file
$rows | Export-Csv -Path $csvFilePath -NoTypeInformation
return $True
}
finally
{
# Release resources used by the search
$searchResult.Dispose()
}
}
# Find all groups managed by someone
$searcher = $Context.BindToObject("Adaxes://rootDSE")
$searcher.SearchFilter = "(&(objectCategory=group)(member=*)(managedBy=*)(name=$groupNamePattern))"
$searcher.PageSize = 500
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.SetPropertiesToLoad(@("managedBy"))
$searcher.VirtualRoot = $True
try
{
$searchResult = $searcher.ExecuteSearch()
$groups = $searchResult.FetchAll()
if ($groups.Count -eq 0)
{
return # No groups found
}
$groupInfos = @{}
foreach ($group in $groups)
{
# Get owner's mail address
$owner = $Context.BindToObjectByDN($group.Properties["managedBy"].Value)
try
{
$ownerMail = $owner.Get("mail")
}
catch
{
continue # Group owner has no mail
}
# Export information on members to CSV
if ($groupInfos.ContainsKey($ownerMail))
{
$groupInfos[$ownerMail] += $group.AdsPath
}
else
{
$groupInfos.Add($ownerMail, @($group.AdsPath)) | Out-Null
}
}
}
finally
{
# Release resources used by the search
$searchResult.Dispose()
}
# Send Report
foreach ($ownerMail in $groupInfos.Keys)
{
# Create temporary CSV file
$fileCreated = CreateCsvFile $groupInfos[$ownerMail] $attributesToExport $csvFilePath
if (!($fileCreated))
{
continue # No users in groups
}
# Send message
Send-MailMessage -To $ownerMail -from $from -SmtpServer $smtpServer -Subject $subject -Body $messageBody -Attachments $csvFilePath
# Remove temporary CSV file
Remove-Item $csvFilePath -Force
}