Most of the customers I work with have just a small number of domain names used for email in their organization. But every now and then I do some work with a customer who has a very large number of email domains.
Often I’m interested in checking the MX records configured for all of those domain names. One example is during an Office 365 migration, when all of the MX records are planned to be moved from their on-premises infrastructure to Exchange Online Protection.
Querying all of the MX records manually would be a long and tedious task. And it would be very boring to have to manually repeat the task at different stages of the migration project.
Fortunately we can query MX records using the Resolve-DnsName cmdlet in PowerShell. Here’s an example:
[PS] C:\>Resolve-DnsName -Name microsoft.com -Type MX | ft -auto Name Type TTL Section NameExchange Preference ---- ---- --- ------- ------------ ---------- microsoft.com MX 10 Answer microsoft-com.mail.protection.outlook.com 10
Here’s an example of a domain name with multiple MX records:
[PS] C:\>Resolve-DnsName -Name qantas.com.au -Type MX Name Type TTL Section NameExchange Preference ---- ---- --- ------- ------------ ---------- qantas.com.au MX 598 Answer cluster-g.mailcontrol.com 10 qantas.com.au MX 598 Answer cluster-m.mailcontrol.com 10 qantas.com.au MX 598 Answer cust20986-1.in.mailcontrol.com 20 qantas.com.au MX 598 Answer cluster-k.mailcontrol.com 10 qantas.com.au MX 598 Answer cust20986-3.in.mailcontrol.com 20 qantas.com.au MX 598 Answer cust20986-2.in.mailcontrol.com 20
As you can see some domain names have one MX record, while others have several. So any script needs to handle multiple domain names *and* multiple MX records.
There’s a few ways we can handle querying multiple domain names. Basically we first need to capture the list of domain names into a variable. If the list of domain names was in a text file we could do this with Get-Content:
[PS] C:Scripts>$domains = @(Get-Content .domains.txt)
If we want to get the list of domain names from the Exchange organization itself we can use Get-AcceptedDomain:
[PS] C:Scripts>$domains = @((Get-AcceptedDomain).DomainName)
Now we simply pipe $domains into Resolve-DnsName and do a little filtering and sorting:
[PS] C:Scripts>$domains | resolve-dnsname -Type MX -Server 8.8.8.8 | where {$_.QueryType -eq "MX"} | Select Name,NameExchange | Sort Name Name NameExchange ---- ------------ exchangeserverpro.mail.onmicrosoft.com exchangeserverpro-mail-onmicrosoft-com.mail.protection.o... exchangeserverpro.net maila.locklan.com.au exchangeserverpro.onmicrosoft.com exchangeserverpro.mail.protection.outlook.com office365bootcamp.net office365bootcamp-net.mail.protection.outlook.com
In the example above I’ve used -Server and one of Google’s DNS server IP addresses to ensure I get the MX record from the public DNS zone and not any internal DNS zones I might be hosting for those domain names.
As you can see it is quite simple to query the MX records for multiple domain names by using PowerShell.
Hi Paul,
I have tried this and I continue to get the error below? I have about 700 domains to query so it would be huge to get this resolved.
Resolve-DnsName : beyeconnections.org : DNS name contains an invalid character
At line:1 char:44
+ $domains = @(Get-Content domainlist.txt) |Resolve-DnsName -Type MX -Server 8.8. …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (beyeconnections.org :String) [Resolve-DnsName], Win32Exception
+ FullyQualifiedErrorId : DNS_ERROR_INVALID_NAME_CHAR,Microsoft.DnsClient.Commands.ResolveDnsName
Hi Paul!
Thank you for the free videos. It helps me a lot. I can now perform send and receive email externally but selected domain only (yahoo, outlook live). When I am trying to send email using my test lab to my gmail account, i am receiving undeliverable email rejected by mx.google.com but I can receive email from gmail. Only outgoing email is the issues. I used dynamic IP (dyndns) and our domain hosted by Ipage.
Meaning, do i need to request to google to allow our IP/Domain? or maybe the issues because of our dynamic IP? Not so sure exactly how to solve this issues. Hope you could help me in this regard. Thank you.
Thank you. Really appreciated.
Hi Paul,
Thank you for your response. Sorry for the confusion. This morning, our domain provider created and pointed already the MX record and route to our local IP.
But before that, Is there anything i need to do in terms of configuration in the router so i can work the email externally? Right now, we are using the trial version of exchange license. Before we purchase the license we would like to execute first in the test environment. Do i need to purchase the license of exchange 2013 to be able to work in external email?
Also, I am not so sure if my DNS in local server is working perfectly but our exchange (test environment) is working fine but internally only. If you have any guidelines, free videos for exch 2013 that would really help a lot on my test server. Thank you so much for your kindness.
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
Try this: https://www.practical365.com/training/exchange-server-2013-boot-camp/
Hi Paul,
I am seeking your help please. I just build a test environment of our exchange server. I used to install Windows Server 2012 and Exchange 2013 in one typical server. I did configure local domain and dns and other pre-req. Now, Exchange is working already locally. Tried also to add the outlook client thru VPN connection and working fine. Further, to be able for us to work with internet and receive email from another domain name, we purchase a domain name in Ipage.com to point the MX in our local Server. They are asking my MX record locally in the server but i did not add any mx record. tried to check thru powershell using this command “Resolve-DnsName -Name almoosatrd.com -type MX | ft -auto” and it shows “almoosatrd.com SOA 3600 Authority exch13.almoosatrd.com hostmaster.almoosatrd.com 37”. is this my MX record? what are the things that i need to do to be able for me to complete the test environment of my exchange server? your responce in this regard is highly appreciated. thank you so much for your help.
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
I checked your domain with mxtoolbox.com and it reports that there is an MX record for your domain. I don’t understand the rest of your question.
I have 2M domain to check txt records, is there any tool?
Hi,
Very nice. How can i do to put the results in a file .xls
Thanks.
Best Regards
Hi, I run this on Windows 10 Pro, and seem to end up with no output. Any thoughts as to why? There are nearly 100 domains in the text file, each on its own line with no spaces before or after. See output below:
PS C:UsersOwnerdesktop> $domains = .domains.txt
PS C:UsersOwnerdesktop> $domains | Resolve-DnsName -Type MX -Server 8.8.8.8 | where {$_.QueryType -eq “MX”} | Select
Name,NameExchange | Sort Name
PS C:UsersOwnerdesktop>
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
$domains = .domains.txt
Should be
$domains = Get-Content .domains.txt
Very nice, thanks.
After I run these commands, how can I get the results into CSV file ? In other words, how can I get the list of valid / invalid domains ?
As always, great info. However…
The caveat to this is that it’s only supported in newer versions of powershell. I created a script to send an email out when something happens, and it worked fine on our exchange boxes and my machine, but when i put it into productions, it wouldn’t work since the utility server is 2008R2 and has an older version of powershell on it. Just an FYI for anyone who was interested.
Good stuff, but the structure of “domains.txt” is? CSV? Difficult for your readers to actually implement with this level of detail. Truly appreciate your efforts.
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
Just a text file. If it was CSV format I would use .csv for the file name and Import-CSV to ingest it.