Script Repository


Notify group owners about changes in group memberships

March 15, 2021
1918

This script notifies group owners when a member has been added or removed from the group owned by them. If a group is a member of other groups, the script will also notify owners of the parent groups.

To use the script with Adaxes, you need to create a business rule triggered after adding or removing a member from a group that runs the script using the Run a program or PowerShell script action.

Edit Remove
PowerShell
# Email message settings
$bodyText = "Group Name: %name%" # TODO: modify me

if ($Context.Action.IsOperationOfType($Context.TargetObject, "remove group members"))
{
    # Email subject for operation 'Remove from group'
    $subject = "User removed from Group %name%" # TODO: modify me
}
else
{
    # Email subject for operation 'Add to group'
    $subject = "New User added to Group %name%" # TODO: modify me
}

# Bind to the member
$member = $Context.BindToObjectByDN("%member%")
$memberList = New-Object "System.Text.StringBuilder"
switch ($member.Class)
{
    "group"
    {
        try
        {
            $memberGuidsBytes = $member.GetEx("adm-MembersGuid")
        }
        catch
        {
            # No members
            return
        }
        
        foreach($memberGuidBytes in $memberGuidsBytes)
        {
            $memberGuid = [Guid]$memberGuidBytes
            $memberPath = "Adaxes://<GUID=$memberGuid>"
            $groupMember = $Context.BindToObject($memberPath)
            
            if($groupMember.Class -ne "user")
            {
                continue
            }
            
            $memberName = $groupMember.Get("name")
            $memberList.Append("`t")
            $memberList.Append($memberName)
            $memberList.AppendLine()
        }
    }
    "user"
    {
        $memberName = $member.Get("name")
        $memberList.Append("`t")
        $memberList.Append($memberName)
        $memberList.AppendLine()
    }
    default
    {
        return
    }
}

if ($memberList.Length -eq 0)
{
    return
}

# Get membership of the group
try
{
    $parentGroupGuidsBytes = $Context.TargetObject.GetEx("adm-MemberOfGuid")
}
catch
{
    $parentGroupGuidsBytes = @()
}

$allGroupGuids = New-Object "System.Collections.Generic.HashSet[System.Guid]"
$targetGroupGuid = [Guid]$Context.TargetObject.Get("ObjectGuid")
[void]$allGroupGuids.Add($targetGroupGuid)
$parentGroupGuidsBytes | %%{[void]$allGroupGuids.Add([Guid]$_)}

# Get email addresses of the group owners
$groupOwnerEmailAddresses = New-Object System.Collections.ArrayList
foreach ($groupGuid in $allGroupGuids)
{
    $groupPath = "Adaxes://<GUID=$groupGuid>"
    $group = $Context.BindToObject($groupPath)
    
    try
    {
        $groupOwnerDN = $group.Get("managedBy")
    }
    catch
    {
        continue
    }

    $groupOwner = $Context.BindToObjectByDN($groupOwnerDN)
    switch ($groupOwner.Class)
    {
        "user"
        {
            try
            {
                $groupOwnerEmail = $groupOwner.Get("mail")
            }
            catch
            {
                continue
            }
            
            $groupOwnerEmailAddresses.Add($groupOwnerEmail)
        }
        "msExchDynamicDistributionList"
        {
            try
            {
                $groupOwnerEmail = $groupOwner.Get("mail")
            }
            catch
            {
                continue
            }
            
            $groupOwnerEmailAddresses.Add($groupOwnerEmail)
        }
        "group"
        {
            try
            {
                $memberGuidsBytes = $groupOwner.GetEx("adm-MembersGuid")
            }
            catch
            {
                continue
            }
    
            foreach ($memberGuidBytes in $memberGuidsBytes)
            {
                $memberGuid = [Guid]$memberGuidBytes
                $memberPath = "Adaxes://<GUID=$memberGuid>"
                $groupMember = $Context.BindToObject($memberPath)
                
                if ($groupMember.Class -ne "user")
                {
                    continue
                }
                
                try
                {
                    $groupOwnerEmail = $groupMember.Get("mail")
                }
                catch
                {
                    continue
                }
                
                $groupOwnerEmailAddresses.Add($groupOwnerEmail)
            }
        }
        default
        {
            continue
        }
    }
}

if ($groupOwnerEmailAddresses.Count -eq 0)
{
    # No owner addresses
    return
}

# Build message body
$bodyTextBuilder = New-Object "System.Text.StringBuilder"
$bodyTextBuilder.Append($bodyText)
$bodyTextBuilder.AppendLine()
$bodyTextBuilder.Append("Full List of Users:")
$bodyTextBuilder.AppendLine()
$bodyTextBuilder.Append($memberList.ToString())

foreach ($groupOwnerEMailAddress in $groupOwnerEmailAddresses)
{
    # Send email
    $Context.SendMail($groupOwnerEMailAddress, $subject, $bodyTextBuilder.ToString(), $NULL)
}

Comments ( 4 )
avatar
Kyle
May 10, 2019
Is this capable of notifying group owners of indirect membership changes? Can this be modified to request approval for this operation via a indirect membership?

For example

User1 (Managed by Manager1) is a member of JobRoleGroup1 (Managed by Manager1) which is a member of NonADIntergratedResourceGroup1 (Managed by Manager2).

When User1 is added to a JobRoleGroup or is removed from a JobRoleGroup, we'd like to notify Manager2 via their the ownership of NonADIntergratedResourceGroup1 that they need to update their System/Access Control List that not intergrated with AD.

Basically we are creating placeholder group for non AD integrated systems so we can use Adaxes reporting and automation functionality. This allows us to run a report on a user and see what they should have access to. It also builds the framework needed for non AD integrated system if they later on AD integration functionality.
avatar
Support
May 13, 2019

Hello Kyle,

> Is this capable of notifying group owners of indirect membership changes?
This script sends a notification to the owner of the parent and a nested group if a user is added/removed from the nested group. If a user is removed only from a parent group, the script will send a notification only to the owner of the parent group. However, we can update the script to send the notifications the way you need.


> Can this be modified to request approval for this operation via a indirect membership?
Yes, it is possible. Do we understand correctly that when a user is added/removed from a group, the operation must be approved by an owner of the nested group the user is also member of? What should be done if the user is not a member of any nested groups? Should the approval request be sent to owners of all nested groups the user is member of?


Please, get back to us at support[at]adaxes.com and we will help you with the solution.

avatar
Arno
Mar 14, 2021
Thank you for the script; To get it running, you need to change 3 bugs.



if (!$sendEmail) --> Should be $sendmail

$Context.SendMail($groupOwnerEMailAddress, $subject, $bodyText, $NULL)
Replace $bodyText with --> $bodyTextBuilder

$bodyTextBuilder.Append("\t")
Replace \ wiht backtick escape character


Thanks
Arno
avatar
Support
Mar 15, 2021
Hello Arno,

Thank you for pointing out the issues. We updated the script accordingly.
Leave a comment