I want to check to see if the email addresses in my contact management system are valid and the best way I can think to do this is to get the MX record for their domain, then open an SMTP connection and see if the remote server accepts the email address as a valid "TO".
Asked
Active
Viewed 1.0k times
5
-
I know everyone loves to script everything, but why not just use nslookup? – joeqwerty Jul 27 '10 at 16:34
-
2'nslookup -type=MX domain.of.choice' will give it. But the output is a bit ugly. – sysadmin1138 Jul 27 '10 at 16:46
-
Ugly is in the eye of the beholder ;) – joeqwerty Jul 27 '10 at 16:56
-
1@joe parsing text programatically is downright evil, and if the output format of the tool you're using ever changes then chances are there goes your parsing script. Much better to have some kind of scripting framework that supports it. – squillman Jul 27 '10 at 17:48
-
@joe: Why not just use nslookup? Frankly only because I am a developer and came to serverfault in complete ignorance. Thanks for pointing me to this tool. In this case, I am specifically looking for a PoSh script, but thanks for this info 'cause I won't have PowerShell everywhere I may need this information. (And I've parsed a whole lot of text results, so that's cool too.) Thanks, Joe! +1 – Kevin Buchan Jul 29 '10 at 11:12
-
@Kevin: Glad to put in my two cents ;) – joeqwerty Jul 29 '10 at 11:37
4 Answers
5
Have a look at the Powershell Dig Cmdlet.
Using this you are able to do this:
PS> $allRecords = Get-Dns -Name mydomain.com -Type MX
PS> write-host $allRecords.RecordsMX
$allRecords
is of type PoshNet.Dns.Response so you can read the properties on it to get your records.
Something else nice about this cmdlet is that you can have it return multiple types of records in a single query.

squillman
- 37,883
- 12
- 92
- 146
-
This looks so perfect. Thanks for the solution and also for pointing me to that cool website. +1 – Kevin Buchan Jul 29 '10 at 11:14
4
function Get-DnsAddressList
{
param(
[parameter(Mandatory=$true)][Alias("Host")]
[string]$HostName)
try {
return [System.Net.Dns]::GetHostEntry($HostName).AddressList
}
catch [System.Net.Sockets.SocketException] {
if ($_.Exception.ErrorCode -ne 11001) {
throw $_
}
return = @()
}
}
function Get-DnsMXQuery
{
param(
[parameter(Mandatory=$true)]
[string]$DomainName)
if (-not $Script:global_dnsquery) {
$Private:SourceCS = @'
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace PM.Dns {
public class MXQuery {
[DllImport("dnsapi", EntryPoint="DnsQuery_W", CharSet=CharSet.Unicode, SetLastError=true, ExactSpelling=true)]
private static extern int DnsQuery(
[MarshalAs(UnmanagedType.VBByRefStr)]
ref string pszName,
ushort wType,
uint options,
IntPtr aipServers,
ref IntPtr ppQueryResults,
IntPtr pReserved);
[DllImport("dnsapi", CharSet=CharSet.Auto, SetLastError=true)]
private static extern void DnsRecordListFree(IntPtr pRecordList, int FreeType);
public static string[] Resolve(string domain)
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
throw new NotSupportedException();
List<string> list = new List<string>();
IntPtr ptr1 = IntPtr.Zero;
IntPtr ptr2 = IntPtr.Zero;
int num1 = DnsQuery(ref domain, 15, 0, IntPtr.Zero, ref ptr1, IntPtr.Zero);
if (num1 != 0)
throw new Win32Exception(num1);
try {
MXRecord recMx;
for (ptr2 = ptr1; !ptr2.Equals(IntPtr.Zero); ptr2 = recMx.pNext) {
recMx = (MXRecord)Marshal.PtrToStructure(ptr2, typeof(MXRecord));
if (recMx.wType == 15)
list.Add(Marshal.PtrToStringAuto(recMx.pNameExchange));
}
}
finally {
DnsRecordListFree(ptr1, 0);
}
return list.ToArray();
}
[StructLayout(LayoutKind.Sequential)]
private struct MXRecord
{
public IntPtr pNext;
public string pName;
public short wType;
public short wDataLength;
public int flags;
public int dwTtl;
public int dwReserved;
public IntPtr pNameExchange;
public short wPreference;
public short Pad;
}
}
}
'@
Add-Type -TypeDefinition $Private:SourceCS -ErrorAction Stop
$Script:global_dnsquery = $true
}
[PM.Dns.MXQuery]::Resolve($DomainName) | % {
$rec = New-Object PSObject
Add-Member -InputObject $rec -MemberType NoteProperty -Name "Host" -Value $_
Add-Member -InputObject $rec -MemberType NoteProperty -Name "AddressList" -Value $(Get-DnsAddressList $_)
$rec
}
}
Get-DnsMXQuery -DomainName "gmail.com"

Marian
- 41
- 1
-
Thanks for the code, Marian. Works like a champ. My solution is already in place, but you can bet I'm saving this code for the future! +1 – Kevin Buchan Dec 12 '11 at 12:37
2
Get-WmiObject -Class MicrosoftDNS_MXType -Namespace root\microsoftdns -ComputerName DC1 -Filter "DomainName='domain.com.'"

Shay Levy
- 969
- 1
- 5
- 5
-
I'm not sure what DC to use for this. I tried my firm's internal domain controllers, but got nothing back for "gmail.com" as the domain. – Kevin Buchan Aug 02 '10 at 16:52
-
Try the one that authenticated your account. You can get it with: $env:LOGONSERVER. BTW dod you try: 'gmail.com.', notice the dot after the domain name. – Shay Levy Aug 02 '10 at 19:41
2
On Server 2012/Windows 8 and above you can use Resolve-DnsName:
Resolve-DnsName -Name mydomain.com -Type MX

Chris Magnuson
- 3,771
- 10
- 42
- 46