Checking if an email address exists using Powershell, Telnet, MX, and PONIES

(Ok, maybe not ponies.)

I’ve stolen and edited a fantastic telnet powershell function from here and am using it to directly telnet to an MX server and check for the existence of a user.

The edited powerful powershell generic telnet method is here:

Function Get-Telnet
{   Param (
        [Parameter(ValueFromPipeline=$true)]
        [String[]]$Commands = @("helo hi"),
        [string]$RemoteHost = "HostnameOrIPAddress",
        [string]$Port = "25",
        [int]$WaitTime = 1000
    )
    #Attach to the remote device, setup streaming requirements
    $Socket = New-Object System.Net.Sockets.TcpClient($RemoteHost, $Port)
    If ($Socket)
    {   $Stream = $Socket.GetStream()
        $Writer = New-Object System.IO.StreamWriter($Stream)
        $Buffer = New-Object System.Byte[] 1024 
        $Encoding = New-Object System.Text.AsciiEncoding

        #Now start issuing the commands
        ForEach ($Command in $Commands)
        {   
            Write-Host $Command
            $Writer.WriteLine($Command) 
            $Writer.Flush()
            Start-Sleep -Milliseconds $WaitTime
        }

        $Result = ""
        #Save all the results
        While($Stream.DataAvailable) 
        {   $Read = $Stream.Read($Buffer, 0, 1024) 
            $Result += ($Encoding.GetString($Buffer, 0, $Read))
        }
    }
    Else     
    {   $Result = "Unable to connect to host: $($RemoteHost):$Port"
    }
    $Result
}

You call it by passing in a param array of commands, a host, and a delay time between each command being sent, e.g.:

Get-Telnet -RemoteHost "192.168.10.1" -Commands "admin","password","terminal pager 0","show run" -WaitTime 1500

I’m only interested in hitting a mail server, so my commands are below.

  1. Start a session: “helo example.com”
  2. Create a new email from a dummy user: “mail from: <[email protected]>”
  3. Set the recipient to the user we’re trying to validate: “rcpt to: <$email>”

If the user exists then the third command returns status code “250”; if not, the status code is “550” – this is all I’ll check for.

The script below will split an email address and get the domain, find out the MX record using Resolve-DnsName, then log on via telnet to the mail server and attempt to create a mail to that user, returning the results of all commands and checking for an occurrence of “550”.

(syntax highlighter is throwing a wobbly if I use an email address inside the code block, so imagine “botATexample.com” is “[email protected]”)

try {        
    $notexists = true

    $email = Read-Host 'Enter an email address to test'
    $columns = $email -split '@'

    $mx = (Resolve-DnsName -Type MX –Name $columns[1] -ea 0)
    if ($mx -ne $null){            
        $notexists = (Get-Telnet -RemoteHost $mx.NameExchange[0] -Commands "helo example.com","mail from: <botATexample.com>","rcpt to: <$email>" -WaitTime 500).Contains("550")
    }
    
    if ($notexists) {Write-Host "Doesn't exist"}
    else {Write-Host "Exists! "}
}
catch [system.exception] {
    Write-Host $_.Exception.ToString()
}

The results might look something like this:

check_email_exists_telnet_powershell

Notes

A helluva lot of mail servers will block this telnet connection! Therefore this is not a reliable method to get all existing users from a list of email addresses; it will result in a LOT of false negatives.

However, those that it returns as real users will certainly be real users.