The script adds users created during a specific period to distribution groups in Microsoft 365 based on a custom attribute value and AD group membership. To run the script, create a scheduled task configured for the Domain-DNS object type and add any managed domain to the Activity Scope.
Parameters:
- $numHours - Specifies the number of hours that will be deducted from the current date. The time period determines recently created users to be affected by the script.
- $addToGroupPropertyName - Specifies the LDAP name of the custom Boolean attribute that should be set to True for a user to get affected by the script.
- $groupDNToGroupName - Maps distinguished names of on-premises AD groups users should be members of with names of the corresponding distribution groups in Microsoft 365 they will get added to.
PowerShell
$numHours = 30 # TODO: modify me
$addToGroupPropertyName = "adm-CustomAttributeBoolean1" # TODO: modify me
$groupDNToGroupName = @{
"CN=Group1,OU=Groups,DC=Domain,DC=com" = "DistGroup1"
"CN=Group2,OU=Groups,DC=Domain,DC=com" = "DistGroup2"
"CN=Group3,OU=Groups,DC=Domain,DC=com" = "DistGroup3"
} # TODO: modify me
function ClearProperty ($adsPath, $addToGroupPropertyName)
{
$user = $Context.BindToObject($adsPath)
$user.Put($addToGroupPropertyName, $NULL)
$user.SetInfo()
}
# Get group members
$groupDnToMemberGuids = @{}
foreach ($dn in $groupDNToGroupName.Keys)
{
$group = $Context.BindToObjectByDN($dn)
$groupDnToMemberGuids.Add($dn, (New-Object "System.Collections.Generic.HashSet[System.Guid]"))
try
{
$group.GetEx("adm-DirectMembersGuid") | %%{$groupDnToMemberGuids[$dn].Add([Guid]$_)}
}
catch { <# Nothing #> }
}
# Build filter
$startTime = [System.DateTime]::UtcNow.AddHours(- $numHours)
$dateGenerilized = [Softerra.Adaxes.Utils.Transform]::ToGeneralizedTime($startTime)
$filter = "(&(sAMAccountType=805306368)(whenChanged>=$dateGenerilized))"
# Search users
$searcher = $Context.TargetObject
$searcher.SearchFilter = $filter
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.PageSize = 500
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.SetPropertiesToLoad(@($addToGroupPropertyName, "objectGUID", "adm-O365ObjectId"))
$searcher.VirtualRoot = $True
try
{
# Execute search
$searchIterator = $searcher.ExecuteSearch()
$searchResults = $searchIterator.FetchAll()
# Connect to Exchange Online
$Context.CloudServices.ConnectExchangeOnline()
foreach ($searchResult in $searchResults)
{
if (!$searchResult.ContainsProperty($addToGroupPropertyName))
{
continue
}
$addToGroup = $searchResult.GetPropertyByName($addToGroupPropertyName).Values[0]
if (!$addToGroup)
{
continue
}
$userIdentity = $Context.GetDisplayNameFromAdsPath($searchResult.AdsPath)
if (!$searchResult.ContainsProperty("adm-O365ObjectId"))
{
$Context.LogMessage("$userIdentity doesn't have a Microsoft 365 account", "Error")
ClearProperty $searchResult.AdsPath $addToGroupPropertyName
continue
}
$objectGuid = [Guid]($searchResult.GetPropertyByName("objectGUID").Values[0])
$objectId = [Guid]($searchResult.GetPropertyByName("adm-O365ObjectId").Values[0])
foreach ($item in $groupDnToMemberGuids.GetEnumerator())
{
if (!$item.Value.Contains($objectGuid))
{
continue
}
# Add user to group
$groupname = $groupDNToGroupName[$item.Key]
try
{
Add-DistributionGroupMember $groupname -Member $objectId.ToString() -BypassSecurityGroupManagerCheck -ErrorAction Stop
}
catch
{
$Context.LogMessage("An error occurred while adding $userIdentity to group $groupName. Error: " + $_.Exception.Message, "Warning")
}
}
ClearProperty $searchResult.AdsPath $addToGroupPropertyName
}
}
finally
{
# Release resources
if ($searchIterator){ $searchIterator.Dispose() }
}