The script creates and emails an HTML-formatted report on users who are members of groups with group names matching a certain pattern. For example, you can use it to locate members of groups that contain admin in their names.
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:
- $groupNameTemplate - Specifies a template for the group names.
- $to - Specifies the recipient of the report.
- $subject - Specifies the notification message subject.
- $reportHeader - Specifies the report header.
- $reportFooter - Specifies the report footer.
PowerShell
$groupNameTemplate = "*admin*" # TODO: modify me
$to = "recipient@domain.com" # TODO: modify me
$subject = "Users who are Members of Administrator Groups" # TODO: modify me
$reportHeader = @"
<h2>Users who are Members of Administrator Groups</h2><br/>
<table border="1">
<tr>
<th>Username</th>
<th>First Name</th>
<th>Last Name</th>
<th>Full Name</th>
<th>Email address</th>
<th>Last time logged on</th>
</tr>
"@ # TODO: modify me
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me
# Find groups that match the template
$searcher = $Context.BindToObject("Adaxes://rootDSE")
$searcher.PageSize = 500
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.SearchFilter = "(&(objectCategory=group)(name=$groupNameTemplate))"
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.VirtualRoot = $True
try
{
$searchResult = $searcher.ExecuteSearch()
$groups = $searchResult.FetchAll()
if ($groups.Count -eq 0)
{
$Context.LogMessage("Found no groups that match the template! The report will not be sent", "Error")
return
}
foreach ($group in $groups)
{
# Bind to the group
$groupObj = $Context.BindToObject($group.AdsPath)
# Get group members
try
{
$memberGuidsByte = $groupObj.GetEx("adm-MembersGuid")
}
catch
{
continue
}
foreach ($memberGuidByte in $memberGuidsByte)
{
$memberGuid = New-Object "System.Guid" (,$memberGuidByte)
$memberGuid = $memberGuid.ToString("B")
$memberPath = "Adaxes://<GUID=$memberGuid>"
# Bind to the member
$member = $Context.BindToObject($memberPath)
if ($member.Class -ine "user")
{
continue
}
# Add member info to the report
$properties = @("sAMAccountName", "givenName", "sn", "cn", "mail", "lastLogonTimeStamp")
$reportHeader += "<tr>"
foreach ($property in $properties)
{
try
{
$value = $member.Get($property)
if ($property -eq "lastLogonTimeStamp")
{
$lastLogonTime = [DateTime]::FromFileTimeUtc([Int64]::Parse($value))
$reportHeader += "<td>$lastLogonTime</td>"
}
else
{
$reportHeader += "<td>" + $value + "</td>"
}
}
catch
{
$reportHeader += "<td>Unspecified</td>"
}
}
$reportHeader += "</tr>"
}
}
}
finally
{
# Release resources used by the search
$searchResult.Dispose()
$reportHeader += "</table>"
}
# Build report
$reportHtml = $reportHeader + $reportFooter
# Send mail
$Context.SendMail($to, $subject, $NULL, $reportHtml)