5

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".

6
  • I know everyone loves to script everything, but why not just use nslookup?
    – joeqwerty
    Jul 27, 2010 at 16:34
  • 2
    'nslookup -type=MX domain.of.choice' will give it. But the output is a bit ugly.
    – sysadmin1138
    Jul 27, 2010 at 16:46
  • Ugly is in the eye of the beholder ;)
    – joeqwerty
    Jul 27, 2010 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, 2010 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 Jul 29, 2010 at 11:12

4 Answers 4

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.

1
  • This looks so perfect. Thanks for the solution and also for pointing me to that cool website. +1 Jul 29, 2010 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"
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 Dec 12, 2011 at 12:37
2

Get-WmiObject -Class MicrosoftDNS_MXType -Namespace root\microsoftdns -ComputerName DC1 -Filter "DomainName='domain.com.'"

2
  • 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. Aug 2, 2010 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 2, 2010 at 19:41
2

On Server 2012/Windows 8 and above you can use Resolve-DnsName:

Resolve-DnsName -Name mydomain.com -Type MX

Source Use PowerShell to Quickly Check Multiple MX Records.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .