Recently, we split up our Office 365 tenant in two separate environments (let's call them Contoso and Fabrikam). We moved over some domains, mailboxes and what not and for the most part, it was a success! (I might need to do a write up on the lessons learned.)
As a final thing, I wanted an Organization Relationship between both tenants. The documentation made it seem easy, like nothing could go wrong...
The time-out
Contoso has about 605 domains registered to their tenant and I wasn't going to type them all out on the Fabrikam side. Good thing there's a command that will get the information for all the domains associated with an Exchange Online organization:
$fi = Get-FederationInformation -DomainName Contoso.com
I waited for a while and saw it loop through all the different domains, and then it just stopped (after about an hour). I tried it a couple of times using both the non-MFA and MFA version of the Exchange PowerShell commands, always failing in the same way.
Although not recommended in a cross-organization arrangement (documentation), the only way I could get it working was by using the -BypassAdditionalDomainValidation
switch:
$fi = Get-FederationInformation contoso.com -BypassAdditionalDomainValidation
The PowerShell limit for domains
Now having a full list of all remote domain names (although not validated), it was time to create the actual relationship:
$fi | New-OrganizationRelationship -Name "Contoso"
Guess again, another undocumented error shows up:
The total number of explicit and implicit subfilters exceeds maximum allowed number of 250. Processing stopped.
+ CategoryInfo : NotSpecified: (:) [New-OrganizationRelationship], ADFilterException
+ FullyQualifiedErrorId : [Server=AM6PR02MB4913,RequestId=16050116-17d4-4ba4-a79a-27191c6ec927,TimeStamp=5/12/2019
6:04:42 PM] [FailureCategory=Cmdlet-ADFilterException] BBB55D68,Microsoft.Exchange.Management.SystemConfiguration
Tasks.NewOrganizationRelationship
+ PSComputerName : outlook.office365.com
So, I split the list of domains in chunks of 250 and create multiple relationships but the error stayed the same. Apparently, through PowerShell, it only works with up to 240 domains 🙄.
Since we're not piping the Federation Information through to the new command, it also needs multiple other parameters:
New-OrganizationRelationship -Name "Contoso-1" -FreeBusyAccessEnabled $true -FreeBusyAccessLevel AvailabilityOnly -DomainNames $domainsPart1 -TargetApplicationUri $fi.TargetApplicationUri -TargetAutodiscoverEpr $fi.TargetAutodiscoverEpr
Just FYI, the documentation also states that the => I made a pull request to the documentation, so this is updated now!-DomainNames
parameter doesn't exist in Exchange Online but I'm using it without issues.
The UI limit for domains
We got the relationships set up, everything was working but I needed to adjust the FreeBusyAccessLevel to a different value. Seems like a good use case for the UI, since it's such a simple fix.
Guess what?
Remember that we only got 240 domains in there. Some trial and error(s) later, it seems like the UI stops working when there are more than 238 domains in the list 🙄.
The final script
In the end, I finally got this script that will read all the domains from the remote organization, split them in chunks of 238 domains and creates one or more relationships for those domains:
# Relationship name
$relPrimaryDomain = "contoso.com"
$relName = "Contoso"
# Defining the chunk size
$chunkSize = 238
# Get federation information
$fi = Get-FederationInformation $relPrimaryDomain -BypassAdditionalDomainValidation
# Set up input and output arrays
$inArray = $fi.DomainNames.ToArray()
$outArray = @()
$parts = [math]::Ceiling($inArray.Length / $chunkSize)
# Splitting the array to chunks of the same size
for($i=0; $i -lt $parts; $i++){
$start = $i*$chunkSize
$end = (($i+1)*$chunkSize)-1
$outArray += ,@($inArray[$start..$end])
}
# Creating relationship with each chunk
$count = 1
$outArray | ForEach-Object {
New-OrganizationRelationship -Name "$relName-$count" -FreeBusyAccessEnabled $true -FreeBusyAccessLevel AvailabilityOnly -DomainNames $_ -TargetApplicationUri $fi.TargetApplicationUri -TargetAutodiscoverEpr $fi.TargetAutodiscoverEpr
$count++
}