How To Validate Ownership of a Large Number of Mail Domains Using Powershell

March 12, 2019 Don Young

Organizations exist that have a large number of mail domains in their on-premises Exchange environment set as accepted domains (let’s say 20+).  As these organizations move to Office 365 using the Hybrid Config Wizard, they will likely notice a problem with the interface that does not allow them to verify domain ownership in bulk.  The screen shots below show what is normally seen at this point in the wizard followed by what is seen when there are too many accepted domains.

This environment was Exchange 2013 CU20

Expected:

Figure 1 – Notice the ‘Verify Domain Ownership’ button

Actual:

Figure 2 – Notice, there is no ‘Validate Domain Ownership’ button

Solution:

While it may be possible to run the Hybrid Config Wizard several times selecting a few namespaces each time, this is certainly not efficient.  Especially if you have hundreds of namespaces in the environment.  (Hey, it could happen!)

A better approach is to use Powershell.

  1. Step one is to get all of the accepted domains from the Exchange on-premises environment

$acceptedDomains = Get-AcceptedDomain

  1. Once those are gathered in a variable, we will need the Federated Domain Proof for each namespace
    1. Note: These will need to be entered as TXT records in external DNS

$proof = $acceptedDomains | Get-FederatedDomainProof -DomainName ([string]$_.domainName) | Select domainName,proof

  1. To make the job easier, create a hash table to store the proofs found

$hash = $null ; $hash = @{} ; $proof | foreach{$hash[$_.proof] = $_.domainName}

  1. The next set of steps will loop through the accepted domains and compare them to TXT records set in external DNS to see if they match

Foreach($Domain in $acceptedDomains){

$txtRecords = $null

$txtRecords = (Resolve-DnsName -Name $Domain.domainName -Type TXT -Server 8.8.8.8).Strings

If($txtRecords){

found=$false

foreach($Record in $txtRecords){

If($hash[$Record]){$found = $true}

}

If($found){[string]$Domain.domainName|out-file .\HasMatchingTXTinDNS.txt -append -noclobber}

else{[string]$Domain.domainName|out-file .\NoMatchingTXTRecordFound.txt -append -noclobber}

}

}

  1. The script above will potentially yield 2 files
    1. The ‘HasMatchingTXTinDNS.txt’ file will have all of the namespaces that are ready to go from an external DNS perspective
    2. The ‘NoMatchingTXTRecordFound.txt’ file will have all of the namespaces that need to have TXT records created for the domain validation to occur
  1. If you had to make the DNS changes and are now coming back to complete the work, you will need to run through steps 1-3 again
  2. The following block of Powershell commands can be used to perform the validations:
    1. Note: For the first run, it would be good to add the ‘-WhatIf’ switch to the ‘Add-FederatedDomain’ command below
    2. These steps can be run and re-run since if an error is encountered, a log file will show those errors

Foreach($Domain in $acceptedDomains){

Try{

Add-FederatedDomain -DomainName ([string]$Domain.domainName) -ErrorAction stop

[string]$Domain.domainName + '~SuccessfullyAdded' | Out-File .\DomainSuccess.txt -append -noClobber

}

Catch [System.Management.Automation.RemoteException]{

If($_.Exception.message -like "*is already configured as a federated domain."){[string]$Domain.domainName + '~AlreadyAdded' | Out-File .\DomainErrors.txt -append -noClobber}

Else{[string]$Domain.domainName + '~SameExceptionDifferentError~' + $_.Exception | Out-File .\DomainErrors.txt -append -noClobber}

}

Catch{[string]$Domain.domainName + '~SomethingUnknownFailed~' + $_.Exception | Out-File .\DomainErrors.txt -append -noClobber

}

}

  1. For fans of one-liners, the following can be used:
    1. Step 4:

$acceptedDomains | Foreach{$txtRecords = $null ; $txtRecords = (Resolve-DnsName -Name $_.domainName -Type TXT -Server 8.8.8.8).strings ; If($txtRecords){$found = $false ; foreach($record in $txtRecords){If($hash[$record]){$found = $true}} ; If($found){[string]$_.domainName | Out-File .\HasMatchingTXTinDNS.txt -append -noClobber}else{[string]$_.domainName | Out-File .\NoMatchingTXTRecordFound.txt -append -noClobber}}}

2. Step 7:

  1. Note: For the first run, it would be good to add the ‘-WhatIf’ switch to the ‘Add-FederatedDomain’ command below
  2. These steps can be run and re-run since if an error is encountered, a log file will show those errors

Foreach($domain in $acceptedDomains){Try{Add-FederatedDomain -DomainName ([string]$domain.domainName) -ErrorAction Stop ; [string]$domain.domainName + '~SuccessfullyAdded' | Out-File .\DomainSuccess.txt -append -noClobber}Catch [System.Management.Automation.RemoteException]{If($_.Exception.Message -like "*is already configured as a federated domain."){[string]$domain.domainName + '~AlreadyAdded' | Out-File .\DomainErrors.txt -append -noClobber}Else{[string]$domain.domainName + '~SameExceptionDifferentError~' + $_.Exception | Out-File .\DomainErrors.txt -append -noClobber}}Catch{[string]$domain.domainName + '~SomethingUnknownFailed~' + $_.Exception | Out-File .\DomainErrors.txt -append -noClobber}}

  1. With the above steps completed, you should be able to run the HCW and this time it will completely bypass the domain validation screen shown in the original screen shots

Previous Article
Office Explorers Podcast: Hear the Best Features of SharePoint Online with New Signature Experts
Office Explorers Podcast: Hear the Best Features of SharePoint Online with New Signature Experts

Our newest episode of the New Signature podcast Office Explorers is live and is focused on all the high-lev...

Next Article
Why should organizations extend beyond SharePoint workflows?
Why should organizations extend beyond SharePoint workflows?

Earlier this year Nintex VP Alex Burton looked at three limitations of out-of-the-box SharePoint Server wor...