Script Repository


Remove all group memberships for a user account

August 09, 2021
6073

The script removes a user from all Active Directory groups except for the primary group and groups specified in the $groupNamesToSkip variable. The script can be used in business rules, custom commands and scheduled tasks.

The $groupNamesToSkip variable specifies the Group Name (pre-Windows 2000) of the groups from which the user should not be removed. If set to $NULL the user for which the script is executed will be removed from all groups except for the primary one.

Edit Remove
PowerShell
$groupNamesToSkip = @("MyGroup1", "MyGroup2", "Department*") # TODO: modify me

function SkipGroup($patterns, $sAMAccountName)
{
    foreach ($pattern in $patterns)
    {
        if ($sAMAccountName -like $pattern)
        {
            return $True
        }
    }
    
    return $False
}

# Get all groups user is a direct member of
$groupGuids = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")

# Get the Primary Group ID
$primaryGroupId = $Context.TargetObject.Get("primaryGroupID")

foreach ($groupGuidBytes in $groupGuids)
{
    # Bind to the group
    $groupGuid = New-Object "System.Guid" (,$groupGuidBytes)
    $groupGuid = $groupGuid.ToString("B")
    $groupPath = "Adaxes://<GUID=$groupGuid>"
    $group = $Context.BindToObject($groupPath)

    # Skip Primary Group
    if ($group.Get("primaryGroupToken") -eq $primaryGroupId)
    {
        continue
    }

    # Skip special groups
    $sAMAccountName = $group.Get("sAMAccountName")
    if (($groupNamesToSkip -ne $NULL) -and 
        (SkipGroup $groupNamesToSkip $sAMAccountName))
    {
        continue
    }

    # Remove user from the group
    $group.Remove($Context.TargetObject.AdsPath)
}

This version of the script sends an email for each user with a list of groups the user has been removed from.

Parameters:

  • $to - Specifies a comma-separated list of recipients of the e-mail notifications. You can use value references to specify recipients. For example, if you use the %adm-ManagerEmail% template, the email will be sent to user managers.
  • $subject - Specifies the subject of the email notifications.
  • $reportHeader - Specifies template for the email notification header. In the emplate, the {0} placeholder will be replaced with a link to the user account in Adaxes Web interface.
  • $reportFooter - Specifies template for the email notification footer.
  • $groupNamesToSkip - Specifies groups from which the user should not be removed. If set to $NULL the user for which the script is executed will be removed from all groups except for the primary one.
You can use value references in the subject, header and footer.
Edit Remove
PowerShell
$groupNamesToSkip = @("MyGroup1", "MyGroup2", "Department*") # TODO: modify me

# E-mail message settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "List of groups user '%name%' has been removed from" # TODO: modify me
$reportHeader = "<b>User {0} has been removed from the following groups:</b><br/>" # 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

function SkipGroup($patterns, $sAMAccountName)
{
    foreach ($pattern in $patterns)
    {
        if ($sAMAccountName -like $pattern)
        {
            return $True
        }
    }
    
    return $False
}

# Get the default Web Interface address
$webInterfaceAddress = "%adm-WebInterfaceUrl%"
if ([System.String]::IsNullOrEmpty($webInterfaceAddress))
{
    $Context.LogMessage("Default web interface address not set for Adaxes service. For details, see http://www.adaxes.com/help/?HowDoI.ManageService.RegisterWebInterface.html", "Warning")
}

# Add link to user
$userGuid = [Guid]$Context.TargetObject.Get("objectGuid")
$reportHeader = [System.String]::Format($reportHeader, "<a href='$webInterfaceAddress`ViewObject.aspx?guid=$userGuid'>%name%</a>")

# Get all groups user is a direct member of
$groupGuidsBytes = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")
$totalRemovedGroups = $groupGuidsBytes.Length - 1
if ($totalRemovedGroups -eq 0)
{
    $Context.LogMessage("This user is a member only the primary group", "Information")
    return
}

# Get the Primary Group ID
$primaryGroupId = $Context.TargetObject.Get("primaryGroupID")

$reportHeader += "<ol>"
foreach ($groupGuidBytes in $groupGuidsBytes)
{
    # Bind to the group
    $groupGuid = [Guid]$groupGuidBytes
    $groupPath = "Adaxes://<GUID=$groupGuid>"
    $group = $Context.BindToObject($groupPath)
   
    # Skip the Primary Group
    if ($group.Get("primaryGroupToken") -eq $primaryGroupId)
    {
        continue
    }

    # Skip special groups
    $sAMAccountName = $group.Get("sAMAccountName")
    if (($groupNamesToSkip -ne $NULL) -and 
        (SkipGroup $groupNamesToSkip $sAMAccountName))
    {
        continue
    }

    # Remove user from the group
    $group.Remove($Context.TargetObject.AdsPath)
    
    # Add group to the report
    $groupDisplayName = [Softerra.Adaxes.Utils.ObjectNameHelper]::GetObjectName($groupPath, "IncludeParentPath")
    $reportHeader += "<li><a href='$webInterfaceAddress`ViewObject.aspx?guid=$groupGuid'>$groupDisplayName</a></li>"
}
$reportHeader += "</ol>"

# Build report
$htmlReport = $reportHeader + "<br/>Total remove groups:$totalRemovedGroups" + $reportFooter

# Send mail
$Context.SendMail($to, $subject, $NULL, $htmlReport)

Preserving List of Group Memberships

To preserve a list of group memberships for future reference, you can save them to a text file, for example. The following version of the script saves a list of groups for a user to a file specified by $filePath.

You can use value references (e.g. %username%) as a part of the file path. Before the script is executed, the value references will be replaced with the property values of the user. For example, if you specify the following: \\server\share\%username%.txt, and run the script on a user whose username is jdoe, the resulting path will be \\server\share\jdoe.txt.
Edit Remove
PowerShell
$filePath = "\\server\share\%username%.txt" # TODO: modify me

# Get all groups user is a direct member of
$groupGuids = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")

# Get the Primary Group ID
$primaryGroupId = $Context.TargetObject.Get("primaryGroupID")

# Create a plain text report
$report = New-Object "System.Text.StringBuilder"
$report.Append("The user was removed from the following groups:")

foreach ($groupGuidBytes in $groupGuids)
{
    # Bind to the group
    $groupGuid = New-Object "System.Guid" (,$groupGuidBytes)
    $groupGuid = $groupGuid.ToString("B")
    $groupPath = "Adaxes://<GUID=$groupGuid>"
    $group = $Context.BindToObject($groupPath)
   
    # Skip the group if it is the user's Primary Group
    if ($group.Get("primaryGroupToken") -eq $primaryGroupId)
    {
        continue
    }

    # Remove user from the group
    $group.Remove($Context.TargetObject.AdsPath)
   
    # Add the group to the report
    $report.AppendLine()
    $report.Append($group.Get("name"))
}

# Create a new text
$file = New-Item -Path $filePath -ItemType File

# Save the report to the file
Add-Content $file $report.ToString()

Comments ( 8 )
avatar
Sean Nicholas
May 15, 2018
These group scripts work awesome as we do remove all groups and e-mail a csv files of the groups for future reference when doing a deprovision of a user. This comes in handy when the service desk has accidentally deprovisioned the wrong user on a rare occasion. I have a new flow that needs to be implemented and that is to remove all the groups except one, so they would have &quot;domain users&quot; and one additional group left. Do you know how to put that into the script?
avatar
Support
May 21, 2018
We have updated the first two scripts according to your request. It is now possible to specify the groups that will be skipped.
avatar
Manuel
Jul 03, 2020
Hi,
this script works great, but I do not see the action in the logs.
How can it be modified so that the user being removed from each group is logged in the Adaxes logs?
avatar
Support
Jul 03, 2020

Hello Manuel,

To pass the remove from group operation through Adaxes pipeline (trigger Business Rules and create a log record), replace this line in the script

$group = $Context.BindToObject($groupPath)

with the following

$group = $Context.BindToObjectEx($groupPath, $True)

avatar
Quinn
May 13, 2021
I have been testing the version of the script that sends the email of the list of groups removed. The script has been working despite the following warning. "The term '$groupNamesToSkip' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again." Also if I add the a group to be removed it fails to skip that group. The group is still removed.
avatar
Support
May 13, 2021
Hello Quinn,

As per our check, the script works just fine. For troubleshooting purposes, please, provide the exact script you are using with all the modifications you made. If you do not want to post the script here, please, email it at support@adaxes.com.
avatar
Quinn
May 13, 2021
Thanks for reply. Here's what I have.

$groupNamesToSkip = @("mmsd.licensing-m365-g3.users") # TODO: modify me

# E-mail message settings
$to = "%adm-InitiatorEmail%" # TODO: modify me
$subject = "List of groups user '%name%' has been removed from" # TODO: modify me
$reportHeader = "<b>User {0} has been removed from the following groups:</b><br/>" # TODO: modify me
$reportFooter = "<hr /><p><i>Please save information for future employee reference.</i></p>" # TODO: modify me

function SkipGroup($patterns, $sAMAccountName)
{
foreach ($pattern in $patterns)
{
if ($sAMAccountName -like $pattern)
{
return $True
}
}

return $False
}

# Get the default Web Interface address
$webInterfaceAddress = "%adm-WebInterfaceUrl%"
if ([System.String]::IsNullOrEmpty($webInterfaceAddress))
{
$Context.LogMessage("Default web interface address not set for Adaxes service. For details, see http://www.adaxes.com/help/?HowDoI.ManageService.RegisterWebInterface.html", "Warning")
}

# Add link to user
$userGuid = [Guid]$Context.TargetObject.Get("objectGuid")
$reportHeader = [System.String]::Format($reportHeader, "<a href='$webInterfaceAddress`ViewObject.aspx?guid=$userGuid'>%name%</a>")

# Get all groups user is a direct member of
$groupGuidsBytes = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")
$totalRemovedGroups = $groupGuidsBytes.Length - 1
if ($totalRemovedGroups -eq 0)
{
$Context.LogMessage("This user is a member only the primary group", "Information")
return
}

# Get the Primary Group ID
$primaryGroupId = $Context.TargetObject.Get("primaryGroupID")

$reportHeader += "<ol>"
foreach ($groupGuidBytes in $groupGuidsBytes)
{
# Bind to the group
$groupGuid = [Guid]$groupGuidBytes
$groupPath = "Adaxes://<GUID=$groupGuid>"
$group = $Context.BindToObject($groupPath)

# Skip the Primary Group
if ($group.Get("primaryGroupToken") -eq $primaryGroupId)
{
continue
}

# Skip special groups
$sAMAccountName = $group.Get("sAMAccountName")
if (($groupNamesToSkip -ne $NULL) -and
(SkipGroup $groupNamesToSkip $sAMAccountName))
{
continue
}

# Remove user from the group
$group.Remove($Context.TargetObject.AdsPath)

# Add group to the report
$groupDisplayName = [Softerra.Adaxes.Utils.ObjectNameHelper]::GetObjectName($groupPath, "IncludeParentPath")
$reportHeader += "<li><a href='$webInterfaceAddress`ViewObject.aspx?guid=$groupGuid'>$groupDisplayName</a></li>"
}
$reportHeader += "</ol>"

# Build report
$htmlReport = $reportHeader + "<br/>Total remove groups:$totalRemovedGroups" + $reportFooter

# Send mail
$Context.SendMail($to, $subject, $NULL, $htmlReport)
avatar
Support
May 14, 2021
Hello Quinn,

Thank you for the provided script. We double-checked it and works just fine. Most probably, there is some unprintable character in your script that causes the issue. We recommend you to directly copy the script from this article (using the Copy button) into the script editor in Adaxes Administration console and modify the variables there.
avatar
Quinn
May 14, 2021
Thanks again for the reply. I copied the script once again from above.. And still received the warning about $groupNamesToSkip. So then I searched and replaced all the "$" in the script with "$". Saved it and the script ran successfully.
Leave a comment