使用 PowerShell V2 的 Send-MailMessage 通过 Gmail 发送邮件

Posted

技术标签:

【中文标题】使用 PowerShell V2 的 Send-MailMessage 通过 Gmail 发送邮件【英文标题】:Send mail via Gmail with PowerShell V2's Send-MailMessage 【发布时间】:2010-11-18 03:35:16 【问题描述】:

我正在尝试弄清楚如何将 PowerShell V2 的 Send-MailMessage 与 Gmail 结合使用。

这是我目前所拥有的。

$ss = New-Object Security.SecureString
foreach ($ch in "password".ToCharArray())

    $ss.AppendChar($ch)

$cred = New-Object Management.Automation.PSCredential "uid@domain.com", $ss
Send-MailMessage  -SmtpServer smtp.gmail.com -UseSsl -Credential $cred -Body...

我收到以下错误

Send-MailMessage : 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 foo.ps1:18 char:21
+     Send-MailMessage <<<<      `
    + CategoryInfo          : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpException
    + FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage

是我做错了什么,还是Send-MailMessage 还没有完全出炉(我在CTP 3)?

一些额外的限制:

    我希望它是非交互式的,所以 Get-Credential 不起作用。 用户帐户不在 Gmail 域中,而是在 Google Apps 注册域中。 对于这个问题,我只对Send-MailMessage cmdlet 感兴趣。通过普通的 .NET API 发送邮件很容易理解。

【问题讨论】:

值得我得到同样的错误,看起来一切正常。我会再玩一些。 好吧,现在你只是在挑剔。 :P 我认为您创建凭据的方式应该没问题。在没有通过应用程序域之前,我只直接对 gmail 进行了身份验证,所以不确定我现在会不会有很大帮助。对不起。 我注意到这是一个老问题(2009 年)并且您在几年前(2011 年)更新了它,但仍然没有公认的答案。这是否意味着您永远无法解决您的问题? 您必须先执行一些 gmail 配置,然后才能从 powershell 发送电子邮件。在谷歌安全控制面板中启用“不太安全的应用程序”。确保禁用 2 因素身份验证。此外,请确保禁用“Captcha” - 如果您在远程服务器上运行脚本,这可能是必需的(在本地计算机上运行时不需要):accounts.google.com/DisplayUnlockCaptcha 【参考方案1】:

我不确定您是否可以使用 Send-MailMessage 更改端口号,因为 Gmail 在端口 587 上工作。无论如何,以下是使用 .NET SmtpClient 通过 Gmail 发送电子邮件的方法:

$smtpClient = New-Object system.net.mail.smtpClient
$smtpClient.Host = 'smtp.gmail.com'
$smtpClient.Port = 587
$smtpClient.EnableSsl = $true
$smtpClient.Credentials = [Net.NetworkCredential](Get-Credential GmailUserID)
$smtpClient.Send('GmailUserID@gmail.com', 'yourself@somewhere.com', 'test subject', 'test message')

【讨论】:

【参考方案2】:

我没有使用 PowerShell V2 的 Send-MailMessage,但我使用 V1 中的 System.Net.Mail.SMTPClient 类将消息发送到 Gmail 帐户以进行演示。这可能有点矫枉过正,但我​​在我的 Windows Vista 笔记本电脑上运行了一个SMTP 服务器(请参阅this link)。如果您在企业中,您将已经有一个邮件中继服务器,这一步不是必需的。拥有 SMTP 服务器后,我可以使用以下代码向我的 Gmail 帐户发送电子邮件:

$smtpmail = [System.Net.Mail.SMTPClient]("127.0.0.1")
$smtpmail.Send("myacct@gmail.com", "myacct@gmail.com", "Test Message", "Message via local SMTP")

【讨论】:

【参考方案3】:

这是我用于 Gmail 的 PowerShell Send-MailMessage 示例...

经过测试且有效的解决方案:

$EmailFrom = "notifications@somedomain.com"
$EmailTo = "me@earth.com"
$Subject = "Notification from XYZ"
$Body = "this is a notification from XYZ Notifications.."
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("username", "password");
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)

只需更改 $EmailTo 和 $SMTPClient.Credentials 中的用户名/密码...不要在您的用户名中包含 @gmail.com...

【讨论】:

感谢我是 serverfault/超级用户成员,这帮助我制作了一个脚本来查看我的服务器何时重新启动。 几乎在那里,但是,您可能会收到错误消息“SMTP 服务器需要安全连接或客户端未经过身份验证。服务器响应是:5.5.1 需要身份验证。”这是因为正如 Google 的自动消息所建议的那样,Gmail 的默认安全设置会阻止连接。因此,只需按照消息中的说明启用“访问安全性较低的应用程序”即可。风险自负。 :) 另外,确保“Captcha”被禁用 - 如果您在远程服务器上运行脚本,这可能是必要的(在本地计算机上运行时不需要):accounts.google.com/DisplayUnlockCaptcha 继续使用 Gmail 帐户进行身份验证失败?我遇到了这个问题,这就是我写这篇文章的原因。我想我肯定有什么问题。事实证明,我需要使用“应用程序密码”而不是我的 Google 帐户密码(因为那是 MFA - 多因素身份验证)。创建应用密码:google.com/settings/security【参考方案4】:

我使用了 Christian 2 月 12 日的解决方案,而且我也刚刚开始学习 PowerShell。至于附件,我正在使用 Get-Member 学习它是如何工作的,并注意到 Send() 有两个定义......第二个定义采用 System.Net.Mail.MailMessage 对象,它允许附件和更强大的功能和有用的功能,如抄送和密送。这是一个带有附件的示例(与他上面的示例混合):

# append to Christian's code above --^
$emailMessage = New-Object System.Net.Mail.MailMessage
$emailMessage.From = $EmailFrom
$emailMessage.To.Add($EmailTo)
$emailMessage.Subject = $Subject
$emailMessage.Body = $Body
$emailMessage.Attachments.Add("C:\Test.txt")
$SMTPClient.Send($emailMessage)

享受吧!

【讨论】:

【参考方案5】:

我是 PowerShell 的新手,我正在搜索有关 PowerShell 的 gmailing。我采用了你们在以前的答案中所做的,并对其进行了一些修改,并提出了一个脚本,该脚本将在添加附件之前检查附件,并获取一组收件人。

## Send-Gmail.ps1 - Send a gmail message
## By Rodney Fisk - xizdaqrian@gmail.com
## 2 / 13 / 2011

# Get command line arguments to fill in the fields
# Must be the first statement in the script
param(
    [Parameter(Mandatory = $true,
               Position = 0,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('From')] # This is the name of the parameter e.g. -From user@mail.com
    [String]$EmailFrom, # This is the value [Don't forget the comma at the end!]

    [Parameter(Mandatory = $true,
               Position = 1,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('To')]
    [String[]]$Arry_EmailTo,

    [Parameter(Mandatory = $true,
               Position = 2,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('Subj')]
    [String]$EmailSubj,

    [Parameter(Mandatory = $true,
               Position = 3,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('Body')]
    [String]$EmailBody,

    [Parameter(Mandatory = $false,
               Position = 4,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('Attachment')]
    [String[]]$Arry_EmailAttachments
)

# From Christian @ ***.com
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SMTPClient($SmtpServer, 587)
$SMTPClient.EnableSSL = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("GMAIL_USERNAME", "GMAIL_PASSWORD");

# From Core @ ***.com
$emailMessage = New-Object System.Net.Mail.MailMessage
$emailMessage.From = $EmailFrom
foreach ($recipient in $Arry_EmailTo)

    $emailMessage.To.Add($recipient)

$emailMessage.Subject = $EmailSubj
$emailMessage.Body = $EmailBody
# Do we have any attachments?
# If yes, then add them, if not, do nothing
if ($Arry_EmailAttachments.Count -ne $NULL)

    $emailMessage.Attachments.Add()

$SMTPClient.Send($emailMessage)

当然,将 GMAIL_USERNAME 和 GMAIL_PASSWORD 值更改为您的特定用户和密码。

【讨论】:

查看此代码为多个收件人***.com/questions/10241816/…【参考方案6】:

这里是:

$filename = “c:\scripts_scott\test9999.xls”
$smtpserver = “smtp.gmail.com”
$msg = New-Object Net.Mail.MailMessage
$att = New-Object Net.Mail.Attachment($filename)
$smtp = New-Object Net.Mail.SmtpClient($smtpServer )
$smtp.EnableSsl = $True
$smtp.Credentials = New-Object System.Net.NetworkCredential(“username”, “password_here”); # Put username without the @GMAIL.com or – @gmail.com
$msg.From = “username@gmail.com”
$msg.To.Add(”boss@job.com”)
$msg.Subject = “Monthly Report”
$msg.Body = “Good MorningATTACHED”
$msg.Attachments.Add($att)
$smtp.Send($msg)

如果它对你有帮助,请告诉我。也使用 send-mailmessage 也在 www.techjunkie.tv

我认为这种方式也更好,更纯粹。

【讨论】:

【参考方案7】:

我同意 Christian Muggli 的解决方案,尽管起初我仍然收到 Scott Weinstein 报告的错误。你是如何克服的:

第一次使用指定的帐户从将要运行的机器上登录到 Gmail。 (即使启用了 Internet Explorer 增强安全配置,没有需要将任何 Google 网站添加到受信任的网站区域。)

或者,在您第一次尝试时,您会收到错误消息,并且您的 Gmail 帐户会收到有关可疑登录的通知,因此请按照他们的说明允许以后从运行此操作的机器上登录。

【讨论】:

【参考方案8】:

这应该可以解决您的问题:

$credentials = New-Object Management.Automation.PSCredential “mailserver@yourcompany.com”, (“password” | ConvertTo-SecureString -AsPlainText -Force)

然后在调用Send-MailMessage -From $From -To $To -Body $Body $Body -SmtpServer $smtpServer URI -Credential $credentials -Verbose -UseSsl时使用凭据

【讨论】:

这是迄今为止最好的答案。无需去 .NET 类,保持 Powershell 语法并这样做!【参考方案9】:

我刚刚遇到了同样的问题并遇到了这篇文章。它实际上帮助我使用本机 Send-MailMessage command-let 运行它,这是我的代码:

$cred = Get-Credential
Send-MailMessage ....... -SmtpServer "smtp.gmail.com" -UseSsl -Credential $cred -Port 587 

但是,为了让 Gmail 允许我使用 SMTP 服务器,我必须登录到我的 Gmail 帐户并在此链接 https://www.google.com/settings/security 下将“访问不太安全的应用程序”设置为“启用”。然后终于成功了!!

【讨论】:

【参考方案10】:

在一台 Windows 8.1 机器上,我得到了 Send-MailMessage 使用以下脚本通过 Gmail 发送带有附件的电子邮件:

$EmFrom = "user@gmail.com"
$username = "user@gmail.com"
$pwd = "YOURPASSWORD"
$EmTo = "recipient@theiremail.com"
$Server = "smtp.gmail.com"
$port = 587
$Subj = "Test"
$Bod = "Test 123"
$Att = "c:\Filename.FileType"
$securepwd = ConvertTo-SecureString $pwd -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $securepwd
Send-MailMessage -To $EmTo -From $EmFrom -Body $Bod -Subject $Subj -Attachments $Att -SmtpServer $Server -port $port -UseSsl  -Credential $cred

【讨论】:

【参考方案11】:

经过多次测试和长期寻找解决方案,我在#PSTip Sending emails using your Gmail account找到了一个功能强大且有趣的脚本代码:

$param = @
    SmtpServer = 'smtp.gmail.com'
    Port = 587
    UseSsl = $true
    Credential  = 'you@gmail.com'
    From = 'you@gmail.com'
    To = 'someone@somewhere.com'
    Subject = 'Sending emails through Gmail with Send-MailMessage'
    Body = "Check out the PowerShellMagazine.com website!"
    Attachments = 'D:\articles.csv'


Send-MailMessage @param

【讨论】:

【参考方案12】:

使用 PowerShell 发送带有附件的电子邮件 -

      $EmailTo = "udit043.ur@gmail.com"  // abc@domain.com
      $EmailFrom = "udit821@gmail.com"  // xyz@gmail.com
      $Subject = "zx"  //subject
      $Body = "Test Body"  // Body of message
      $SMTPServer = "smtp.gmail.com" 
      $filenameAndPath = "G:\abc.jpg"  // Attachment
      $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body)
      $attachment = New-Object System.Net.Mail.Attachment($filenameAndPath)
      $SMTPMessage.Attachments.Add($attachment)
      $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
      $SMTPClient.EnableSsl = $true 
      $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("udit821@gmail.com", "xxxxxxxx"); // xxxxxx-password
      $SMTPClient.Send($SMTPMessage)

【讨论】:

【参考方案13】:

在让这些脚本中的任何一个用于在 powershell 中发送邮件时,我遇到了很大的问题。原来您需要为您的 gmail 帐户创建一个应用程序密码才能在脚本中进行身份验证。现在它可以完美运行了!

【讨论】:

这是一个干净的 sn-p ***.com/questions/10241816/…

以上是关于使用 PowerShell V2 的 Send-MailMessage 通过 Gmail 发送邮件的主要内容,如果未能解决你的问题,请参考以下文章

powershell Powershell尝试捕获,仅适用于v2

powershell équivalentdeinvoke-webrequest pour powershell V2。

使用 PowerShell V2 的 Send-MailMessage 通过 Gmail 发送邮件

用于从存储帐户 V2 检索存储帐户资源 ID、blob 资源 ID 的 Powershell 命令

Microsoft Graph PowerShell v2 发布公开预览版 - 一半的大小,加速的自动化体验

Microsoft Graph PowerShell v2 发布公开预览版 - 一半的大小,加速的自动化体验