ค้นหาเว็บไซต์

Send-MailMessage: การส่งอีเมลด้วย PowerShell


คุณสามารถใช้ cmdlet Send-MailMessage ในตัวเพื่อส่งอีเมล SMTP จาก PowerShell คุณสามารถใช้ cmdlet นี้เพื่อส่งอีเมลใน PowerShell เวอร์ชัน 2.0 และใหม่กว่า (ก่อนหน้านี้คุณสามารถใช้ .Net

System.Net.Mail

คลาสเพื่อส่งข้อความอีเมล) Send-MailMessage ช่วยให้คุณสามารถส่งข้อความพร้อมไฟล์แนบ ใช้รูปแบบ HTML สำหรับเนื้อหาของข้อความ เปิดใช้งานการแจ้งเตือนการส่ง ส่งข้อความถึงผู้รับหลายคนพร้อมกัน ฯลฯ ในบทความนี้ เราจะดูวิธีใช้

Send-MailMessage

cmdlet เพื่อส่งข้อความอีเมลจากภายในสคริปต์ PowerShell ของคุณ

PowerShell Send-MailMessage Cmdlet: พารามิเตอร์และตัวอย่าง

ในการรับไวยากรณ์ของ cmdlet ให้รันคำสั่งนี้:

get-help Send-MailMessage
Send-MailMessage [-To] <String[]> [-Subject] <String> [[-Body] <String>] [[-SmtpServer] <String>] [-Attachments <String[]>] [-Bcc <String[]>] [-BodyAsHtml] [-Cc <String[]>] [-Credential <PSCredential>] [-DeliveryNotificationOption {None | OnSuccess | OnFailure | Delay | Never}] [-Encoding <Encoding>] -From <String> [-Port <Int32>] [-Priority {Normal | Low | High}] [-UseSsl] [<CommonParameters>]
The Send-MailMessage cmdlet sends an email message from within Windows PowerShell.

นี่คือตัวเลือกหลัก:

  • จาก - คือที่อยู่ผู้ส่ง คุณสามารถส่งข้อความอีเมลในนามของที่อยู่อีเมลใดก็ได้ หากเซิร์ฟเวอร์ SMTP ไม่ตรวจสอบที่อยู่ผู้ส่ง (รีเลย์ที่ไม่ระบุตัวตน)

  • ถึง - ที่อยู่อีเมลของผู้รับ

  • SMTPServer - ที่อยู่ของเซิร์ฟเวอร์ SMTP ที่คุณต้องการส่งอีเมล

ไม่จำเป็นต้องใช้ที่อยู่เซิร์ฟเวอร์ SMTP หากคุณตั้งค่าที่อยู่เซิร์ฟเวอร์อีเมลในตัวแปรสภาพแวดล้อม $PSEmailServer:

$PSEmailServer = "smtp.a-d.site"

คำสั่ง PowerShell ต่อไปนี้จะส่งอีเมลพร้อมหัวเรื่องและเนื้อความที่ระบุไปยังผู้รับหลายคน

Send-MailMessage -From 'ps-script@a-d.site' -To 'serveradmin@a-d.site','helpdesk@a-d.site' -Subject "Test Email Alert" -Body "This is email body text" -SmtpServer 'smtp.a-d.site'

คุณสามารถส่งอีเมลไปยังกล่องจดหมายของผู้รับตั้งแต่หนึ่งกล่องขึ้นไป ไปยังแชนเนล Teams หรือไปยังที่อยู่ในกลุ่มการแจกจ่าย Exchange

เพื่อให้ง่ายต่อการแก้ไขแอตทริบิวต์ของ cmdlet คำสั่ง Send-MailMessage สามารถแสดงได้ดังนี้:

Send-MailMessage `
-SmtpServer smtp.a-d.site `
-To 'serveradmin@a-d.site','helpdesk@a-d.site' `
-From 'ps-script@a-d.site' `
-Subject "Test" `
-Body "Sending email using PowerShell" `
-Encoding 'UTF8'

โปรดทราบว่าในคำสั่งสุดท้าย เราได้ตั้งค่าการเข้ารหัส UTF8 เพิ่มเติมสำหรับอีเมล มิฉะนั้น ถ้าหัวเรื่องหรือเนื้อความของอีเมลมีอักขระที่ไม่ใช่ ANSI จะแสดงอย่างไม่ถูกต้อง

Windows PowerShell ใช้การเข้ารหัส ANSI และ ASCII ตามค่าเริ่มต้น หากคุณได้อัปเดตเวอร์ชัน PS ของคุณเป็น PowerShell Core โปรดทราบว่าเวอร์ชันนี้ใช้การเข้ารหัส UTF-8 ตามค่าเริ่มต้นแล้ว

คุณสามารถระบุผู้รับหลายคนโดยใช้พารามิเตอร์:

  • To

    - ที่อยู่อีเมลของผู้รับปกติ

  • Cc

    - ที่อยู่อีเมลสำหรับส่งสำเนา (CC) ของข้อความอีเมล

  • Bcc

    - ที่อยู่อีเมลที่จะได้รับสำเนาของอีเมล แต่จะไม่แสดงเป็นผู้รับข้อความ

คุณสามารถเปิดใช้งานการแจ้งเตือนการส่งสำหรับอีเมลโดยใช้ -DeliveryNotificationOptions (ซึ่งช่วยให้คุณได้รับแจ้งเมื่อผู้รับได้รับอีเมล) ประเภทการแจ้งเตือนที่ใช้ได้คือ:

  • OnSuccess (แจ้งเตือนหากการจัดส่งสำเร็จ)

  • OnFailure (แจ้งเตือนหากการส่งไม่สำเร็จ)

  • ล่าช้า (แจ้งเตือนหากการจัดส่งล่าช้า)

คุณสามารถระบุได้หลายตัวเลือกในคำสั่งเดียว:

Send-MailMessage … -DeliveryNotificationsOptions 'OnSuccess', 'OnFailure'

การแจ้งเตือนการจัดส่งจะถูกส่งไปยังกล่องจดหมายที่ระบุไว้ในฟิลด์ "จาก"

คุณยังสามารถกำหนดลำดับความสำคัญของข้อความอีเมล (ไม่แสดงในบางไคลเอ็นต์):

-Priority High|Low|Normal

หากคุณต้องการเพิ่มไฟล์แนบในอีเมล ให้ใช้ตัวเลือก - ไฟล์แนบ ในตัวอย่างด้านล่าง เราจะส่งอีเมลในรูปแบบ HTML (-BodyAsHtml) และแนบ file1.txt และ report.xsls จากไดรฟ์ในเครื่อง

$MailMessage = @{
To = "admin@a-d.site"
Bcc = "manager@a-d.site", "manager2@a-d.site"
From = "DC server <dc01@a-d.site>"
Subject = "DC Server Report"
Body = "<h1>Welcome!</h1> <p><strong>Generated:</strong> $(Get-Date -Format g)</p>”
Smtpserver = "smtp.gmail.com"
Port = 587
UseSsl = $true
BodyAsHtml = $true
Encoding = “UTF8”
Attachment = “C:\Logs\file1.txt”, “C:\Logs\report.xlsx”
}
Send-MailMessage @MailMessage -Credential $cred

ในตัวอย่างนี้ เราได้แทนที่ชื่อที่แสดงของผู้รับด้วย "เซิร์ฟเวอร์ DC"

นี่คือลักษณะของอีเมล HTML พร้อมไฟล์แนบในอินเทอร์เฟซ Gmail

เมื่อคุณส่งอีเมลในนามของกล่องจดหมายที่ใช้ร่วมกันของ Exchange/Microsoft 365 ซึ่งคุณได้รับสิทธิ์ SendAs คุณสามารถระบุได้ว่าควรบันทึกสำเนาของข้อความในโฟลเดอร์รายการที่ส่งของ กล่องจดหมายต้นทาง สำหรับสิ่งนั้น ให้เปิดใช้งานพารามิเตอร์ MessageCopyForSentAsEnabled สำหรับกล่องจดหมาย:

Set-Mailbox it_dept -MessageCopyForSentAsEnabled $True

การใช้ Send-MailMessage กับ SMTP Auth และ TLS/SSL

ตามค่าเริ่มต้น cmdlet Send-MailMessage จะส่งอีเมลผ่านพอร์ต SMTP ที่ไม่ได้เข้ารหัสเริ่มต้น TCP 25 หากเซิร์ฟเวอร์ SMTP ของคุณอนุญาตให้ส่งอีเมลโดยใช้โปรโตคอลที่เข้ารหัสเท่านั้น คุณสามารถระบุหมายเลขพอร์ตใน -Port แอตทริบิวต์ (ส่วนใหญ่มักเป็น 465 หรือ 587) และตัวเลือก -UseSsl:

-SmtpServer 'smtp.a-d.site' -Port 465 -UseSsl

ข้อผิดพลาดจะเกิดขึ้นหากใบรับรอง SSL ของเซิร์ฟเวอร์ SMTP ไม่ตรงกับ FQDN ที่ระบุใน HELO:

Send-MailMessage: The remote certificate is invalid according to the validation procedure.

คุณอาจได้รับข้อผิดพลาดเมื่อส่งอีเมลโดยใช้การเข้ารหัส SSL/TLS:

Send-MailMessage : Unable to read data from the transport connection: net_io_connectionclosed

ในกรณีนี้ ขอแนะนำให้คุณตรวจสอบสิ่งต่อไปนี้

  • พอร์ต SMTP ที่ระบุเปิดอยู่และเข้าถึงได้จากคอมพิวเตอร์ของคุณ:

    Test-NetConnection smtp.a-d.site -Port 465
  • ลองใช้พอร์ต SMTP อื่น ตัวอย่างเช่น 587 (msa) แทน 465 (smtps) พอร์ต 587 เป็นค่าเริ่มต้นเมื่อใช้ส่วนขยาย STARTTLS

  • หากคุณใช้ระบบปฏิบัติการรุ่นเก่ากว่า (Windows Server 2012/Windows 8 และต่ำกว่า) คุณต้องเปิดใช้งานการสนับสนุนโปรโตคอล TLS 1.2 สำหรับ PowerShell โดยใช้คำสั่ง:

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

ตารางด้านล่างแสดงการตั้งค่าเซิร์ฟเวอร์ SMTP สำหรับผู้ให้บริการอีเมลสาธารณะยอดนิยมที่คุณสามารถใช้เพื่อส่งข้อความจาก PowerShell (โปรดทราบว่าคุณต้องอนุญาตให้ส่งอีเมลผ่าน SMTP ในอินเทอร์เฟซบัญชี):

NameSMTP Server AddressPortEncryption Type
Gmailsmtp.gmail.com587

25

465

TLS

TLS

SSL

Microsoft (Office) 365smtp.office365.com587TLS
Outlook.comsmtp-mail.outlook.com587TLS
Yahoosmtp.mail.yahoo.com587TLS
iCloud mailsmtp.mail.me.com587TLS
AOL smtp.aol.com465SSL

หากเซิร์ฟเวอร์ SMTP ไม่อนุญาตให้ใช้อีเมลที่ไม่ระบุชื่อ (การส่งต่อถูกปฏิเสธ) คุณจะเห็นข้อผิดพลาดนี้:

5.7.1 Client was not authenticated.

หรือ :

The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM.

จากนั้น คุณสามารถรับรองความถูกต้องกับเซิร์ฟเวอร์ SMTP โดยใช้ตัวเลือก -ข้อมูลประจำตัว

คุณสามารถโต้ตอบเพื่อขอข้อมูลประจำตัวของผู้ใช้สำหรับการรับรองความถูกต้อง:

Send-MailMessage …… -Credential (Get-Credential)

คุณยังสามารถระบุข้อมูลรับรองบัญชีเพื่อใช้สำหรับการตรวจสอบสิทธิ์ในตัวแปร:

$cred = Get-Credential
Send-MailMessage ... -Credential $cred

จะส่งอีเมลผ่าน Gmail SMTP ด้วย PowerShell ได้อย่างไร

หากต้องการส่งอีเมลจากกล่องจดหมายของคุณในบริการอีเมลสาธารณะ ขอแนะนำให้ใช้ รหัสผ่านสำหรับแอป แทนรหัสผ่านเพื่อเข้าถึงบัญชี/กล่องจดหมายของคุณ ตัวอย่างเช่น ใน Gmail คุณสามารถสร้างรหัสผ่านสำหรับแอปได้หลังจากที่คุณเปิดใช้งานการตรวจสอบสิทธิ์สองปัจจัยสำหรับบัญชี Google ของคุณ สร้างและคัดลอกรหัสผ่านสำหรับแอปของคุณบน Google (เป็นรหัสผ่าน 16 อักขระ)

ตัวอย่างต่อไปนี้แสดงวิธีการส่งอีเมลจากกล่องจดหมาย Google ของคุณโดยใช้ PowerShell คุณต้องใช้รหัสผ่านสำหรับแอปแทนรหัสผ่านบัญชี Google ของคุณ ในตัวอย่างนี้ เราจะระบุรหัสผ่านแอปสำหรับเชื่อมต่อกับเซิร์ฟเวอร์ SMTP ของ Gmail โดยตรงในโค้ดสคริปต์ PowerShell

$From = "sender@gmail.com"
$To = "recipient@gmail.com"
$Subject = "Test PowerShell email from $($env:computername)"
$Body = "some message test "
$Password = "your_google_app_password" | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $From, $Password
Send-MailMessage -From $From -To $To -Subject $Subject -Body $Body -SmtpServer "smtp.gmail.com" -port 587 -UseSsl -Credential $Credential

โปรดทราบว่า PowerShell บันทึกคำสั่งด้วยรหัสผ่านข้อความล้วนในไฟล์ประวัติคำสั่ง PowerShell อ่านบทความเกี่ยวกับวิธีใช้และป้องกันรหัสผ่านในสคริปต์ PowerShell

คำเตือนจะปรากฏขึ้นเมื่อคุณใช้คำสั่ง Send-MailMessage ใน PowerShell Core 7.x เวอร์ชันใหม่:

WARNING: The command 'Send-MailMessage' is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage at this time. See https://aka.ms/SendMailMessage for more information.

cmdlet Send-MailMessage ใช้คลาส .NET SmtpClient ที่ไม่สนับสนุนวิธีการรับรองความถูกต้องสมัยใหม่ รวมถึง Microsoft Modern Authentication ขอแนะนำให้คุณใช้ Graph API เพื่อส่งอีเมลจาก PowerShell ผ่าน Microsoft 365/Exchange Online (โดยใช้

Send-MgUserMail

cmdlet หรือ

Invoke-RestMethod

เพื่อเรียกใช้เมธอด sendMail ผ่าน REST API)

บทความที่เกี่ยวข้อง