为什么在我的PowerShell脚本中不会对SmtpClient进行身份验证?

时间:2017-06-15 02:52:57

标签: powershell email authentication smtpclient

我尝试从PowerShell脚本发送电子邮件,但我无法通过SMTP服务器对其进行正确身份验证。

$fromEmail = 'local@example.com';
$toEmail = 'remote@example.net';
$mailUser = 'myUsername';
$mailPassword = 'myPassword';
$smtpServer = 'smtp.example.com';
$smtpPort = 587;
$content = 'Email message content';
$subject = 'Email message subject';

$credentials = New-Object System.Net.NetworkCredential $mailUser, $mailPassword;

$server = New-Object System.Net.Mail.SmtpClient $smtpServer, $smtpPort;
$server.UseDefaultCredentials = $false;
$server.EnableSSL = $true;
$server.Credentials = $credentials
$server.Send($fromEmail, $toEmail, $subject, $content);

当我尝试在powershell提示符中运行上述操作时,会导致指定拒绝中继访问的错误。

Exception calling "Send" with "4" argument(s): "Client does not have permission to submit mail to this server. The
server response was: 4.7.1 <remote@example.net>: Relay access denied"
At line:1 char:1
+ $server.Send($fromEmail, $toEmail, $subject, $content);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

如果我尝试使用Thunderbird或PHP的Swiftmailer发送电子邮件以及相同的服务器和凭据设置,它可以正常工作。从查看后缀日志看起来好像SmtpClient甚至没有尝试进行身份验证,而只是尝试匿名发送邮件。

这是thunderbird的一个很好的日志条目:

Jun 14 21:17:42 services postfix/submission/smtpd[16653]: connect from unknown[xxxx]
Jun 14 21:17:43 services postfix/submission/smtpd[16653]: 59074F96E: client=unknown[xxxx], sasl_method=PLAIN, sasl_username=local@example.com

而SmtpClient的条目如下:

Jun 14 22:11:16 services postfix/submission/smtpd[16824]: connect from unknown[xxxx]
Jun 14 22:11:16 services postfix/submission/smtpd[16824]: NOQUEUE: reject: RCPT from unknown[xxxx]: 454 4.7.1 <remote@example.net>: Relay access denied; from=<local@example.com> to=<remote@example.net> proto=ESMTP helo=<WTFv2>

作为测试我还尝试使用我的gmail凭据通过gmail地址发送,并且由于没有身份验证而失败。

Exception calling "Send" with "4" argument(s): "The SMTP server requires a secure connection or the client was not
authenticated. The server response was: 5.5.1 Authentication Required. Learn more at"
At line:1 char:1
+ $server.Send($fromEmail, $toEmail, $subject, $content);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

我在这里缺少什么?为什么.net SmtpClient不发送身份验证以允许邮件通过?

2 个答案:

答案 0 :(得分:1)

您可以尝试这种方式,这是我用于Gmail的方式,我使用System.Net.NetworkCredential获取凭据(来自我的C#代码):

$smtpServer = "smtp.gmail.com"
$smtpServerport = "587"
$emailSmtpUser = "toto@myDomain.com"
$emailSmtpPass = "toto.123"

$emailMessage = New-Object System.Net.Mail.MailMessage
$emailMessage.From = "toto@myDomain.com"
foreach ($addr in $to)
{
  $emailMessage.To.Add($addr)
}
foreach ($attachment in $attachments)
{
  $emailMessage.Attachments.Add($attachment)
}
$emailMessage.Subject = "The subject"
$emailMessage.IsBodyHtml = $true
$emailMessage.Body = $body

$smtpClient = New-Object System.Net.Mail.SmtpClient($smtpServer , $smtpServerport)
$smtpClient.EnableSsl = $true
$smtpClient.Credentials = New-Object System.Net.NetworkCredential($emailSmtpUser , $emailSmtpPass);

$SMTPClient.Send( $emailMessage )

答案 1 :(得分:1)

看来至少有两个问题导致了这个问题。我最终尝试了很多事情,但我并不完全确定哪种组合最终解决了这个问题。

首先,我确定问题是由于我的服务器仅提供PLAIN身份验证方法。即使在启用TLS的连接上,SmtpClient似乎也不会使用PLAIN。如果SmtpClient不支持任何提供的身份验证方法,那么它显然只是在没有身份验证的情况下继续。

我试图找到支持的身份验证方法列表,但也无法使用。 This blog post引导我尝试NTLM和LOGIN。使用NTLM,它尝试进行身份验证,但无法成功。 LOGIN最终运作正常。

问题的第二部分,我不完全确定底层问题是什么。启用LOGIN最初不起作用所以我决定将代码转换为C#并编译并在那里运行测试程序。该计划立即奏效。我回到Powershell并再次尝试我的代码,看看我是否能找到差异,它突然开始工作了。

以某种方式编译和运行C#版本会导致Powershell版本也能正常工作。如果有人能解释为什么这可能是我想知道的。