The script adds a user to a business unit if they haven't logged on to Exchange Online for a certain period of time.
To update the business unit automatically on a periodical basis, create a scheduled task for User objects that runs the script.
Parameters:
- $businessUnitName - Specifies the business unit name.
- $inactivityDurationThreshold - Specifies the number of days a user should be inactive in Exchange Online to be included in the business unit.
PowerShell
$businessUnitName = "My Unit" # TODO: modify me
$inactivityDurationThreshold = "30" # Days. TODO: modify me
function UpdateBusinessUnit($operation, $businessUnitDNs)
{
# Search Business Unit
$businessUnitsPath = $Context.GetWellKnownContainerPath("BusinessUnits")
$searcher = $Context.BindToObject($businessUnitsPath)
$searcher.SearchFilter = "(&(objectCategory=adm-BusinessUnit)(name=$businessUnitName))"
$searcher.PageSize = 500
try
{
$searchResultIterator = $searcher.ExecuteSearch()
$searchResults = $searchResultIterator.FetchAll()
if ($searchResults.Length -eq 0)
{
$Context.LogMessage("Business Unit '$businessUnitName' not found.", "Warning")
return
}
elseif ($searchResults.Length -gt 1)
{
$Context.LogMessage("Found more than one Business Unit with the following name '$businessUnitName'", "Warning")
return
}
$dn = $searchResults[0].Properties["distinguishedName"].Value
if ((-not($businessUnitDNs.Contains($dn)) -and $operation -eq "Remove") -or
($businessUnitDNs.Contains($dn) -and $operation -eq "Add"))
{
return # No need to add or remove the user
}
# Update Business Unit
$unit = $Context.BindToObject($searchResults[0].AdsPath)
$rules = $unit.GetMembershipRules()
if ($operation -eq "Remove")
{
# Find Membership Rule for the user and remove it
foreach ($rule in $rules)
{
if (!$rule.IsObjectAffected($Context.TargetObject))
{
continue
}
# Save changes
$rules.Remove($rule)
$unit.SetMembershipRules($rules)
$unit.SetInfo()
break
}
}
elseif ($operation -eq "Add")
{
# Create Membership Rule
$rules = $unit.GetMembershipRules()
$includeRule = $rules.Create("ADM_BUSINESSUNITMEMBERSHIPTYPE_SPECIFIC")
$includeRule.Exclude = $False
$includeRule.Object = $Context.TargetObject
# Save changes
$rules.Add($includeRule)
$unit.SetMembershipRules($rules)
$unit.SetInfo()
}
}
finally
{
# Release resources
if ($searchResultIterator){ $searchResultIterator.Dispose() }
}
}
# Get Business Units user is member of
try
{
$memberOfBusinessUnitDNs = $Context.TargetObject.GetEx("adm-MemberOfBusinessUnits")
}
catch
{
$memberOfBusinessUnitDNs = @()
}
$businessUnitDNs = New-Object "System.Collections.Generic.HashSet[System.String]"
$memberOfBusinessUnitDNs | %%{[void]$businessUnitDNs.Add($_)}
# Check recipient type and location
if ($Context.TargetObject.RecipientLocation -ne "ADM_EXCHANGERECIPIENTLOCATION_OFFICE365" -or
$Context.TargetObject.RecipientType -ne "ADM_EXCHANGERECIPIENTTYPE_MAILBOXENABLED")
{
if ($businessUnitDNs.Count -ne 0)
{
UpdateBusinessUnit "Remove" $businessUnitDNs
}
return
}
# Get last logon date from Exchange Online
try
{
$mailboxParams = $Context.TargetObject.GetMailParameters()
}
catch
{
$Context.LogMessage("An error occurred retrieving Exchange properties. Error: " + $_.Exception.Message, "Warning")
return
}
$lastLogonDate = $mailboxParams.UsageInfo.LastLogonDate
$date = [Datetime]::Now.AddDays(- $inactivityDurationThreshold)
# Check last logon date
if ($lastLogonDate -gt $date)
{
UpdateBusinessUnit "Remove" $businessUnitDNs
}
else
{
UpdateBusinessUnit "Add" $businessUnitDNs
}