SOLVED

Add Users to Group in AD and remove anyone created after 93 days for Onboard

Iron Contributor

Hello,

I need to create a powershell script to add specific Users by Titles to a group in AD and remove anyone created after 93 days.

 

The first part of my script is as follows:

 

Import-Module ActiveDirectory
$Days = 92
$Time = (Get-Date).Adddays(-($Days))
$List = "(title -like 'Title1') -or (title -like 'Title2') -or (Description -like 'Description1') -or (Description -like 'Description2')"
Get-ADUser -Filter $List -Properties whenCreated,Title,DisplayName | Where {$_.whenCreated -gt $Time} | Select DisplayName, Title, whenCreated | export-csv c:\temp\OnBoard.csv -NoTypeInformation

 

As they age, they need to be removed from the group. This is for onboarding new users for Orientation.

 

How would I write the Add-ADGroupMember in this script with this criteria so that it removes them after 93 days? Leaving just new users created in the last 92 days.

 

I could not find anything about whenCreated with specific titles, so I did my best to list them and confirmed it is accurate.

 

Thanks,

Denise

 

 

 

2 Replies
best response confirmed by Denise Child (Iron Contributor)
Solution

@Denise Child 

 

Hi, Denise.

 

Here's a template to get you started.

 

Points of note:

 

  1. You already know everything you need to know to fully-leverage server-side filtering, which removes the performance hit associated with client-side filtering (on the days elapsed);
  2. The script performs all the changes locally and then commits the changes with a single call back to AD (via Set-ADGroup), which avoids inefficiently calling Add- and Remove-ADGroupMembership on a per-user basis;
  3. It works with just the delta (adding/removing only where applicable) rather than rebuilding the membership entirely;
  4. I didn't bother putting in any change reporting but you could readily add that into the expunge and add sections.

 

$HasChanged = $false;
$Threshold = [datetime]::Now.Date.AddDays(-92);
$Filter = { (whenCreated -ge $Threshold) -and ((title -eq "title1") -or (title -eq "title2") -or (description -eq "description1") -or (description -eq "description2")) };

# Retrieve currently-eligible members.
$Memberships = [System.Collections.Generic.List[string]] (Get-ADUser -Filter $Filter).distinguishedName;

# Retrieve the group along with the current membership.
$Group = Get-ADGroup -Identity "<guid> or <dn> or <name>" -Properties members;

#region Expunge ineligible existing members.
# First, expunge anyone from the current membership who does not feature in the current memberhip list.
if ($Group.PropertyNames.Contains("members") -and ($Group.members.Count -gt 0))
{
    # We need to copy the existing members out to an array before the "members" collection on the group object.
    $Group.Members.CopyTo(($MemberDNs = [string[]]::new($Group.Members.Count)), 0)

    foreach ($ExistingMember in $MemberDNs)
    {
        if (-not $Memberships.Contains($ExistingMember))
        {
            # Remove the person from the group.
            $null = $Group.members.Remove($ExistingMember);
            $HasChanged = $true;
        }
        else
        {
            # Remove the person from the list of people to add, since they already are a member of the group.
            $null = $Memberships.Remove($ExistingMember);
        }

    }
}
#endregion

#region Add new eligible members
if ($Memberships.Count -gt 0)
{
    $HasChanged = $true;

    foreach ($NewMember in $Memberships)
    {
        $null = $Group.members.Add($NewMember);
    }
}
#endregion

# Finally, if there's been any changes to the group's membership, commit the changes back to Active Directory.
if ($HasChanged)
{
    Set-ADGroup -Instance $Group;
}

# Bada-bing, bada-bang. We're done.

 

Cheers,

Lain

@LainRobertson
Lain, thank you so much for your help! You rock!
I added my checks and ran this several times to confirm no issues and got it scheduled to run once a week.

I started out trying to figure this with Azure Dynamic Groups, since it seemed to be the likely place, then I went to Power Automate, that turned out to be too difficult. The group used for this is going to be added to Teams so the new users can get their Training videos and learning materials.
1 best response

Accepted Solutions
best response confirmed by Denise Child (Iron Contributor)
Solution

@Denise Child 

 

Hi, Denise.

 

Here's a template to get you started.

 

Points of note:

 

  1. You already know everything you need to know to fully-leverage server-side filtering, which removes the performance hit associated with client-side filtering (on the days elapsed);
  2. The script performs all the changes locally and then commits the changes with a single call back to AD (via Set-ADGroup), which avoids inefficiently calling Add- and Remove-ADGroupMembership on a per-user basis;
  3. It works with just the delta (adding/removing only where applicable) rather than rebuilding the membership entirely;
  4. I didn't bother putting in any change reporting but you could readily add that into the expunge and add sections.

 

$HasChanged = $false;
$Threshold = [datetime]::Now.Date.AddDays(-92);
$Filter = { (whenCreated -ge $Threshold) -and ((title -eq "title1") -or (title -eq "title2") -or (description -eq "description1") -or (description -eq "description2")) };

# Retrieve currently-eligible members.
$Memberships = [System.Collections.Generic.List[string]] (Get-ADUser -Filter $Filter).distinguishedName;

# Retrieve the group along with the current membership.
$Group = Get-ADGroup -Identity "<guid> or <dn> or <name>" -Properties members;

#region Expunge ineligible existing members.
# First, expunge anyone from the current membership who does not feature in the current memberhip list.
if ($Group.PropertyNames.Contains("members") -and ($Group.members.Count -gt 0))
{
    # We need to copy the existing members out to an array before the "members" collection on the group object.
    $Group.Members.CopyTo(($MemberDNs = [string[]]::new($Group.Members.Count)), 0)

    foreach ($ExistingMember in $MemberDNs)
    {
        if (-not $Memberships.Contains($ExistingMember))
        {
            # Remove the person from the group.
            $null = $Group.members.Remove($ExistingMember);
            $HasChanged = $true;
        }
        else
        {
            # Remove the person from the list of people to add, since they already are a member of the group.
            $null = $Memberships.Remove($ExistingMember);
        }

    }
}
#endregion

#region Add new eligible members
if ($Memberships.Count -gt 0)
{
    $HasChanged = $true;

    foreach ($NewMember in $Memberships)
    {
        $null = $Group.members.Add($NewMember);
    }
}
#endregion

# Finally, if there's been any changes to the group's membership, commit the changes back to Active Directory.
if ($HasChanged)
{
    Set-ADGroup -Instance $Group;
}

# Bada-bing, bada-bang. We're done.

 

Cheers,

Lain

View solution in original post