Send-MailMessage: การส่งอีเมลด้วย PowerShell
คุณสามารถใช้ cmdlet Send-MailMessage ในตัวเพื่อส่งอีเมล SMTP จาก PowerShell คุณสามารถใช้ cmdlet นี้เพื่อส่งอีเมลใน PowerShell เวอร์ชัน 2.0 และใหม่กว่า (ก่อนหน้านี้คุณสามารถใช้ .Net
System.Net.Mailคลาสเพื่อส่งข้อความอีเมล) Send-MailMessage ช่วยให้คุณสามารถส่งข้อความพร้อมไฟล์แนบ ใช้รูปแบบ HTML สำหรับเนื้อหาของข้อความ เปิดใช้งานการแจ้งเตือนการส่ง ส่งข้อความถึงผู้รับหลายคนพร้อมกัน ฯลฯ ในบทความนี้ เราจะดูวิธีใช้
Send-MailMessagecmdlet เพื่อส่งข้อความอีเมลจากภายในสคริปต์ PowerShell ของคุณ
PowerShell Send-MailMessage Cmdlet: พารามิเตอร์และตัวอย่าง
ในการรับไวยากรณ์ของ cmdlet ให้รันคำสั่งนี้:
get-help Send-MailMessageSend-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 ในอินเทอร์เฟซบัญชี):
| Name | SMTP Server Address | Port | Encryption Type |
| Gmail | smtp.gmail.com | 587 25 465 | TLS TLS SSL |
| Microsoft (Office) 365 | smtp.office365.com | 587 | TLS |
| Outlook.com | smtp-mail.outlook.com | 587 | TLS |
| Yahoo | smtp.mail.yahoo.com | 587 | TLS |
| iCloud mail | smtp.mail.me.com | 587 | TLS |
| AOL | smtp.aol.com | 465 | SSL |
หากเซิร์ฟเวอร์ 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-MgUserMailcmdlet หรือ
Invoke-RestMethodเพื่อเรียกใช้เมธอด sendMail ผ่าน REST API)




