Scripting – Powershell Script Alternative to Telnet SMTP Connection test

 

  The script hereafter is outdated and has been replaced by a newer version (i.e. PowerShell Module).  Please Check the Download page for latest version.

Hello World,

This post will be quick quite short today.  

When an Exchange administrator needs to check if the mail server is working as expected and accessible through the network, the first and most know test consist of initiating a telnet connection against the Exchange server on the specified port (usually port 25). You can find extensive explanation and procedure by reading the use-telnet-to-test-smtp-communication-exchange-2013-help documentation on Microsoft Website.

Usually, Telnet client can be found on a computer on the network or can be installed quickly from Windows servers features.  However, in one specific situation, it was not allowed and not possible to install the Telnet client.  This was strongly enforced by the Security IT Officer.  At first, we were thinking that we would not be able to provide support as requested.  But then, we started thinking about using PowerShell scripting in order to  replace the classic Telnet test any Exchange admin would perform….

Overview

In this section, we quickly compare possible ways to assess SMTP connectivity.  The most known approach would be to use Telnet client.  However, if the client is not installed, you can always fallback to Powershell.   Using Powershell, you can either perform a really basic test and ensure that network connectivity is there through the Test-netconnection cmdlet.  If you need to perform deeper investigation on Exchange server and SMTP mail flow, you can use the custom script that would provide possibly a good alternative to the Telnet Client.

Testing smtp communication using Telnet Client

To test SMTP connection while using Telnet client, you would open a command prompt, issue the following command

Telnet <%MAIL SERVER%> 25 
HELO 
MAIL FROM :<%SenderEmail%>
RCPT TO: <%REcipientEmail%>
DATA
Subject : Test Message
<% Your Message %> 

.

If everything goes fine, you should see a message that says the message is queued for delivery. 

SMTP_TELNET

Click on Picture for Better Resolution

 

You can check that the message has been indeed delivered by opening the mailbox of the recipients.  This is all fine and this would be the standard approach when Telnet Client is available and can be used.  

Testing SMTP Connection using PowerShell – Basic Test

If Telnet client is not available, an alternative would be to use the Test-netconnection PowerShell Cmdlet.    So, you would open a Powershell Console and issue the following command

Test-netconnection -computername <%MAIL_SERVER_NAME%> -Port <%PORT_NUMBER%>

This provides really a basic test and simply indicates if the remote server is listening to the specified port and that the client performing the test can connect to this remote server.   

Obviously, when working with Exchange server, this simple test might not be enough.  Indeed, you could be able to establish a connection to your Exchange server but other issues could arise while effectively sending an email message.  So, this command is not enough 

Testing SMTP Connection using PowerShell – Advanced Test

While looking on internet for some solution, we came across this blog post  (https://www.techtutsonline.com/powershell-alternative-telnet-command/).  Again, the script was simply checking the initial connection but no further command could have been issued.  However, the script was using new-object System.Net.Sockets.TcpClient option.   Using this object, it would be possible to connect and issue additional commands.

After some additional search, we found a script that was basically providing what we needed.  The script to perform telnet smtp test has been published by Glen Scales and can be found at https://gsexdev.blogspot.com/2006/09/doing-smtp-telnet-test-with-powershell.html. This was exactly what we were looking for and we have been using this script as needed.  However, after some times, some users have asked us to change a little bit the script and the way it was working. 

The modified script is presented here.  It’s really light touched modification and credits are obviously going to Glen Scales for providing the great PowerShell Script

###########################################################################
# Script_Name : Test-Exchange-SMTP.ps1
# Description : Perform a Telnet SMTP Test connection and send email using 
#               Powershell instead of Telnet Client 
# Author      : Glen Scales  
# Updated by  : Hector
# Modified by : Griffon (Minor Modification to fit specific requirements
# Date : 10 July 2020 
# Version : 1.0 
# Disclaimer : Script provided AS IS. Use it at your own risk....
# You can use this script and distribute it as long as credits are kept 
###########################################################################

param ([String] $remotehost, $port="25", [String] $From,[String]$To,[String] $Subject="Test Message $(get-date)",[String] $HEL="HELO")
if ($remotehost -eq "" -or $MailFrom -eq "" -or $RCPT -eq "")
{
"Please specify at minimum the Exchange Server Name or IP, Sender, Recipient"
return;
}

#-------------------------------#
# OUTPUT on screen              #
#-------------------------------# 
function readResponse {
while($stream.DataAvailable)
{
$read = $stream.Read($buffer, 0, 1024)
write-host -n -foregroundcolor cyan ($encoding.GetString($buffer, 0, $read))
""
}
}

#---------------------------#
# Make the Connection       #
#---------------------------#

$socket = new-object System.Net.Sockets.TcpClient($remoteHost, $port)

if($socket -eq $null) { return; }

$stream = $socket.GetStream()
$writer = new-object System.IO.StreamWriter($stream)
$buffer = new-object System.Byte[] 1024
$encoding = new-object System.Text.AsciiEncoding
readResponse($stream)

#------------------------#
# HELO OR EHLO           #
#------------------------#

write-host -foregroundcolor yellow $HEL
""
$writer.WriteLine($HEL)
$writer.Flush()
start-sleep -m 500
readResponse($stream)

#------------------------#
# Mail FROM              #
#------------------------#

$command = "MAIL FROM: $from"
write-host -foregroundcolor yellow "MAIL FROM: $from"
""
$writer.WriteLine($command)
$writer.Flush()
start-sleep -m 500
readResponse($stream)

#------------------------#
# RECIPIENT              #
#------------------------#

$command = "RCPT TO: $To"
write-host -foregroundcolor yellow $command
""
$writer.WriteLine($command)
$writer.Flush()
start-sleep -m 500
readResponse($stream)

#-----------------------------------------------------------------------#
# Check is Msg is sent or simply test SMTP connection                   #
#-----------------------------------------------------------------------#

if ($Subject -eq "") {

#--QUIT - Only Test connection ---#
$command = "QUIT"
write-host -foregroundcolor yellow $command
""
$writer.WriteLine($command)
$writer.Flush()
start-sleep -m 500
readResponse($stream)
## Close the streams
$writer.Close()
$stream.Close()

} else {

$command = "DATA"
write-host -foregroundcolor yellow $command
""
$writer.WriteLine($command)
$writer.Flush()
start-sleep -m 500
readResponse($stream)

write-host -foregroundcolor yellow "Subject : $Subject"
""
#$writer.WriteLine("`r")
$writer.WriteLine("subject:$Subject `r")
$writer.Flush()
start-sleep -m 500
readResponse($stream)

write-host -foregroundcolor yellow "."
""
$writer.WriteLine(".")
$writer.Flush()
start-sleep -m 500
readResponse($stream)

#-------------------#
# QUIT              #
#-------------------#

$command = "QUIT"
write-host -foregroundcolor yellow $command
""
$writer.WriteLine($command)
$writer.Flush()
start-sleep -m 500
readResponse($stream)
## Close the streams
$writer.Close()
$stream.Close()
}

How to use the script ?

You have to run it using Powershell Console.  You have to check the PowerShell Execution Policy within your organization. If the policy is set to Unrestricted, you can execute the script directly from PowerShell Console.  If the policy is set to restricted or signed, you can run the script from a command prompt by using the following syntax

powershell.exe -ExecutionPolicy bypass -command “Test-Exchange-SMTP.PS1 -remotehost <%SMTP SERVERNAME OR IP%> -FROM <%Sender Email Address%> -To <%Recipient Address%>”

You can also run it from PowerShell ISE but you will need to modify the script a little bit…

The minimum parameters that need to be passed are

  • SMTP Mail Server NAme or IP address
  • Sender email address
  • Recipient Email address

So, to test your smtp connection, the most basic command to be used would be the following

.\Test-Exchange-SMTP.PS1 -remotehost <%SMTP SERVERNAME OR IP%> -FROM <%Sender Email Address%> -To <%Recipient Address%>

 

SMTP_EHLO_2

Click on Picture for Better Resolution

You can also pass the parameters

  •  -Port .  The script uses by default port 25 but if you are using another port, pass it as a parameter
  • -HEL.  The script uses by default the HELO command to initiate the connection but if you prefer to use EHLO, you can also pass it as a parameter 

SMTP_EHLO

Click on Picture for Better Resolution

If you have some custom configuration or you want to play with the other parameters available, you can issue the following command

.\Test-Exchange-SMTP.PS1 -remotehost <%SMTP SERVERNAME OR IP%> -FROM <%Sender Email Address%> -To <%Recipient Address%> -Port <%YourCustomPort%> -HEL EHLO

 

Final Notes

As explained, we have encountered more situation where Telnet Client software was either not available or simply not allowed on the network we were working on.  This situation makes it difficult to debug SMTP Connection issues and forced us to find other ways to perform the Classic Telnet test.  PowerShell was the clear way to look for an alternative solution.  Browsing the net, we quickly found that we were not the only one trying to find an alternative method to Telnet. 

Based on the script provided by Glen Scales, we have slightly modified it and we are now able to perform Telnet test connection against an Exchange Server, we are able to see the Reply of the server when we issue the SMTP commands and based on this information, we are able to assess and debug issues with mail flow. 

We are already working on a better version and/or way to test smtp connection through PowerShell.  In a few days/weeks, we will publish the improved version of this script which will greatly ease usage and distribution… This post was just the appetizer  🙂

Till Next time

See ya

 

 

 

 

Leave a Reply