I have been doing a lot of Exchange on-premises-to-Exchange Online migrations over the last few years, and because of that, I use mxtoolbox.com frequently to query MX, SPF, DMARC, and DKIM records. Wouldn’t it be convenient to get a simple overview of those records in a PowerShell function? This blog post will show you how 🙂
How it works
PowerShell has a built-in cmdlet for retrieving DNS records in Windows, Resolve-DnsName. With this, you can query records and specify what DNS server to connect to and what type of record (A, CNAME, MX, NS, etc.) to retrieve. However, the DNSClient-PS module also provides this functionality and is compatible with Linux, macOS, and Windows. The function Get-MailDomainInfo I created uses this module and returns the information you need to get a clear overview of the servers and options used for one or more domains. By default, it connects to the 1.1.1.1 (CloudFlare) DNS server, but you can specify another one using the -DNSServer parameter.
Example output
In the screenshot below, the output is shown for microsoft.com:

If you specify a domain that can’t be found, it will show an error message:

If the domain exists but is missing some records or services, it will return ‘Not enabled’ for those. In this example, my domain returns the domain name, auto-discovery, SPF (including values from included statements, if any), DMARC, and DKIM records. (I used the -DNSserver parameter here to specify another DNS server in this example.) It will also indicate whether the domain is DNSSEC-enabled.

Note: You can specify multiple domains, separated by commas. Get-MailDomainInfo -DomainName powershellisfun.com, microsoft.com will return info for both domains.
The script
Below is the script’s contents. You can save it to C:\data, for example, and use it as a function in all your PowerShell sessions by adding it to your profile:
- Notepad $profile - Add ". c:\data\Get-MailDomainInfo.ps1" - Quit/Save and start a new PowerShell session
You can also run it in your PowerShell session, as mentioned below.

Afterward, you can use Get-MailDomainInfo -DomainName Microsoft.com, for example.
function Get-MailDomainInfo {
param(
[parameter(Mandatory = $true)][string[]]$DomainName,
[parameter(Mandatory = $false)][string]$DNSserver = '1.1.1.1'
)
$info = foreach ($domain in $DomainName) {
#Check if domain name is valid, output warning it not and continue to the next domain (if any)
try {
#Check if DnsClient-PS module is installed
if (-not (Get-Module -Name DnsClient-PS -ListAvailable -ErrorAction SilentlyContinue)) {
try {
Install-Module DnsClient-PS -Scope CurrentUser -Confirm:$false -Force:$true -ErrorAction Stop
Import-Module DnsClient-PS -ErrorAction Stop
Write-Host ("Installed required module DnsClient-PS, continuing...")
}
catch {
Write-Warning ("Error installing required DnsClient-PS module for Linux/macOS DNS queries, exiting...")
return
}
}
#Test if Domain name exists
Resolve-Dns -Query $domain -NameServer $DNSserver -ErrorAction Stop | Out-Null
#Set $erorfind to desired error output. 'not enabled', for example
$errorfinding = 'Not enabled'
#Retrieve all mail DNS records
$autodiscoverA = (Resolve-Dns -Query "autodiscover.$($domain)" -QueryType A -NameServer $DNSserver -ErrorAction SilentlyContinue).IPAddress
$autodiscoverCNAME = if ((Resolve-Dns -Query "autodiscover.$($domain)" -QueryType CNAME -NameServer $DNSserver -ErrorAction SilentlyContinue).Answers) { (Resolve-Dns -Query "autodiscover.$($domain)" -QueryType CNAME -NameServer $DNSserver -ErrorAction SilentlyContinue).Answers.canonicalname.tostring() }
$dkim1 = (Resolve-Dns -Query "selector1._domainkey.$($domain)" -QueryType CNAME -NameServer $DNSserver -ErrorAction SilentlyContinue).AllRecords.domainname.original[0].tostring().TrimEnd('.')
$dkim2 = (Resolve-Dns -Query "selector2._domainkey.$($domain)" -QueryType CNAME -NameServer $DNSserver -ErrorAction SilentlyContinue).AllRecords.domainname.original[0].tostring().TrimEnd('.')
$dmarc = (Resolve-Dns -Query "_dmarc.$($domain)" -QueryType TXT -NameServer $DNSserver -ErrorAction SilentlyContinue).answers.escapedtext
$dnssec = (Resolve-Dns -Query $domain -QueryType DNSKEY -ErrorAction SilentlyContinue).Answers
$mx = (Resolve-Dns -Query $domain -QueryType MX -NameServer $DNSserver -ErrorAction SilentlyContinue).Answers.Exchange
$spf = (Resolve-Dns -Query $domain -QueryType TXT -NameServer $DNSserver -ErrorAction SilentlyContinue).Answers.escapedtext | Select-String 'v=spf'
$includes = ((Resolve-Dns -Query $domain -QueryType TXT -NameServer $DNSserver -ErrorAction SilentlyContinue).Answers.escapedtext | Select-String 'v=spf').line.split(' ') | Select-String -Pattern 'Include:'
if ($dkim1.length -le 1 -and $dkim2.Length -le 1) {
$dkim = $errorfinding
}
else {
$dkim = "$($dkim1), $($dkim2)"
}
if ($null -eq $dmarc) {
$dmarc = $errorfinding
}
if ($null -eq $mx) {
$mx = $errorfinding
}
if ($null -eq $spf) {
$spf = $errorfinding
}
if ($null -eq $autodiscoverCNAME) {
$autodiscoverCNAME = $errorfinding
}
if (($autodiscoverA).count -gt 1 -or $null -ne $autodiscoverCNAME) {
$autodiscoverA = $errorfinding
}
if ($null -eq $includes) {
$includes = $errorfinding
}
else {
$foundincludes = foreach ($include in $includes) {
if ((Resolve-Dns -NameServer $DNSserver -Query $include.ToString() -ErrorAction SilentlyContinue)) {
[PSCustomObject]@{
SPFIncludes = $include.ToString().Split(':')[1] + " : " + (Resolve-Dns -NameServer $DNSserver -Query $include.ToString().Split(':')[1] -QueryType txt).answers.escapedtext
}
}
else {
[PSCustomObject]@{
SPFIncludes = $errorfinding
}
}
}
}
if ($dnssec.length -lt 1) {
$dnssec = $errorfinding
}
else {
$dnssec = 'Enabled'
}
[PSCustomObject]@{
'Domain Name' = $domain
'Autodiscover IP-Address' = $autodiscoverA
'Autodiscover CNAME ' = "$($autodiscoverCNAME.TrimEnd('.'))"
'DKIM Record' = $dkim
'DMARC Record' = "$($dmarc)"
'DNSSEC' = $dnssec
'MX Record(s)' = if ($mx -ne $errorfinding) { ($mx).Value.TrimEnd('.') -join ', ' } else { $errorfinding }
'SPF Record' = "$($spf)"
'SPF Include values' = if ("$($foundincludes.SPFIncludes)") { "$($foundincludes.SPFIncludes)" -replace "all", "all`n`b" } else { $errorfinding }
}
}
catch {
Write-Warning ("{0} not found" -f $domain)
}
}
return $info
}
Download the script(s) from GitHub here.
Hello,
Nice script, maybe I am missing something, but it didn’t return any information.
Please advise.
Thanks
It’s a Function, if you run it… Then it becomes available in your session (PowerShell prompt, ISE or VSCode) So, you can run it from powershell.exe of pwsh.exe by “. c:\scripts\get-MailDomainInfo.ps1), for example. Then you can use Get-MailDomainInfo and use the function like described in the blog post.
I updated this blog post to explain it better, my bad!