Share this post:
PowerShell を使用して電子メールを送信することは素晴らしい機能であり、正しい方法で実装すれば非常に役に立ちます。
PowerShell を使用して電子メールを送信するには、Send-MailMessage PowerShell CmdLet を使用しますが、使用を開始する前にいくつかの前提条件があります。
いくつかの素晴らしい例に飛び込んで、PowerShell を使った電子メール送信機能のルック&フィールをつかみましょう。
目次
Send Email Using PowerShell – Easy Example
PowerShell の Send-MailMessage CmdLet で、PowerShell から電子メールを送信することができるようになりました。
Send-MailMessage -To "recipient’s email address" -From "sender’s email address" -Subject "Your message subject" -Body "Message text!" -Credential (Get-Credential) -SmtpServer "SMTP server" -Port 587
重要:このコードが動作するためには、Portを除くすべてのパラメータの値を、ケースに応じた実際の値に置き換える必要があります。
この簡単な例では、Send-MailMessage PowerShell CmdLetのいくつかの必要なパラメーターを使用して、シンプルな電子メールを受信者に送信しています:
- -Toパラメーター値は、受信者の電子メールアドレスです
- -Fromパラメーター値は、送信者の電子メールアドレスです
- -Subjectパラメーター値は、電子メールの件名テキストです
- -Bodyパラメーター値は、電子メールのコンテンツです。
- -Credentialパラメータは、SMTPサーバーのユーザー名とパスワードの認証情報です。 この記事の以下のサブトピックで、クレデンシャルを渡す方法を説明していますので、ご覧ください。
- -SmtpServer パラメーターの値は、SMTPのサーバーアドレスです。
- -Port パラメーターの値は、SMTPが電子メールメッセージをリッスンするポート番号です。
注意: -From パラメーターに、SMTPサーバーに送信者として登録されていない送信者の電子メールアドレスを使用した場合、SMTPサーバーのサポートから、登録されていない送信者の電子メールアドレスから電子メールを送信しようとしているというメールを受け取る可能性があります。
ここでは、私のSMTPサーバーのアドレスと認証情報を使って受信したメールを示します。 ご覧のとおり、添付ファイル付きの電子メールを送信した例で、Gmail の受信トレイに件名と本文の一部が表示されています。
メール本文には、PowerShellを使用して送信されたメールメッセージの内容が表示されています。 これは、PowerShell を使用して、件名テキスト、MailJet SMTP サーバー経由、本文は単なるプレーンテキスト、メールに添付ファイルを付けてメールを送信した例です。
Send-MailMessage CmdLetのパラメーターは他にもたくさんあります。MailMessage CmdLetのパラメータは他にもたくさんあり、この記事の少し先の例で見ていきます。
しかし、PowerShellを使用したメール送信の例やニュアンスに触れる前に、メール送信に必要な前提条件、つまりSMTPサーバーとSMTPサーバー認証資格を明確にしておきましょう。
どの SMTP サーバーを使用するか、SMTP サーバーを取得する方法
さて、PowerShell を使用して電子メールを送信したいのだが、なぜ SMTP サーバーの話をしているのかと疑問に思われるでしょう。 封筒を直接相手に届けていましたか? もちろん、そうではありません。
つまり、SMTPサーバーとは、私たちがPowerShellで書いたメールを、私たちに代わって受信者に送ってくれるプロバイダーなのです。
SMTPサーバーは、私たちがPowerShellで書いた電子メールを、私たちの代わりに受信者に送信してくれるプロバイダーです。
SMTPとは、Simple Mail Transfer Protocolの略で、サーバー上のアプリケーションが電子メールを送信するための、合意された「言語」または通信プロトコルです。
例として、またコードをテストするために、アカウントの作成とセットアップが簡単なMailJetを使用しました。
MailJetでアカウントを作成すると、SMTP設定を見ることができます。
- SMTPサーバーのアドレス(「in-v3.mailjet.com」)、
- 使用されるポート(587)、
- SMTP認証のためのユーザー名と
- パスワード。
これらの情報は、Send-MailMessage PowerShell CmdLetを使用して電子メールを送信する際に重要となりますので、PowerShellの電子メール送信機能を使用する前に確認してください。
1つ目はよりシンプルですが、SMTP サーバーのパスワードがソース コードにアクセスした他の人に見えるため、安全性が低くなります。
2つ目はステップが1つ増えますが、SMTP 資格情報を提供するときに使用できる外部ファイルにパスワードを保護および暗号化しておくことができるため、より安全です。
ソース コード内の可視パスワードで SMTP 資格情報を送信する (より安全ではない)
この例では、Send-MailMessage CmdLet にいくつかのパラメータを提供していますが、この例を説明するための最も重要なパラメータは次のとおりです。
- SmtpServer
- Credential
注意:この例を動作させるためには、これらの変数の値をあなた自身のデータに置き換えてください。
$EmailFrom = "sender’s email address" $EmailTo = "recipient’s email address" $EmailSubject = "Learn PowerShell With Dejan - ImproveScripting.com." $EmailBody = "This email has an attachment error log." $SMTPserver= "SMTP server"$username="your_user_name" $password = "your_password" | ConvertTo-SecureString -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($username, $password)Send-MailMessage -ErrorAction Stop -from "$EmailFrom" -to "$EmailTo" -subject "$EmailSubject" -body "$EmailBody" -SmtpServer "$SMTPserver" -Attachments "$home\Documents\PSlogs\Error_Log.txt" -Priority "Normal" -Credential $credential -Port 587 -UseSsl
SmtpServerのパラメータ値にはSMTPサーバーのアドレスが含まれています。例えば、MailJet SMTPサーバーは「in-v3.mailjet.com」です。
CredentialパラメータはユーザーとパスワードのSMTPサーバー資格情報をラップし、PSCredentialオブジェクトとして渡す必要があります。 パスワードはプレーンテキストではなく、SecureStringデータタイプであるため、PSCredentialオブジェクトの作成にパスワードを渡す際には特別な注意を払う必要があります。
$password = "your_password" | ConvertTo-SecureString -AsPlainText -Force
すでに述べたように、この方法はそれほど複雑ではありませんが、SMTP サーバーのパスワードをソース コード内でプレーンテキストとして保持しているため、セキュリティ上の問題があります。
最後に、この例を使った結果と受信したメールを示します。
ソースコードでパスワードを隠してSMTP認証情報を送信する (より安全に)
この例では、SMTP認証情報を提供しながら電話をかけます。 この例では、Send-MailMessage CmdLetの呼び出し時にSMTP認証情報を提供しますが、今回はパスワードは表示されません。
まず、外部の txt ファイルでパスワードを一度だけ暗号化し、そのファイルを使用して、ソース コードで必要なときにいつでもパスワードを復号化して読み取ることができます。
Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File -FilePath "C:\Users\dekib\Documents\PSCredential\MailJet.txt"
これでパスワードが暗号化されて外部ファイルに保存され、Send-MailMessage CmdLetを呼び出す際に使用できるようになりました。
以下は、暗号化されたパスワードを外部のtxtファイルで使用する方法を示す例です。
注意: この例を動作させるためには、これらの変数の値をあなた自身のデータに置き換えてください: $EmailFrom, $EmailTo, $SMTPserver, $username.
$EmailFrom = "sender’s email address" $EmailTo = "recipient’s email address" $EmailSubject = "Learn PowerShell With Dejan - ImproveScripting.com." $EmailBody = "This email has an attachment error log." $SMTPserver= "SMTP server"$EncryptedPasswordFile = "$home\Documents\PSCredential\MailJet.txt"$username="your_user_name" $password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString$credential = New-Object System.Management.Automation.PSCredential($username, $password)Send-MailMessage -ErrorAction Stop -from "$EmailFrom" -to "$EmailTo" -subject "$EmailSubject" -body "$EmailBody" -SmtpServer "$SMTPserver" -Attachments "$home\Documents\PSlogs\Error_Log.txt" -Priority "Normal" -Credential $credential -Port 587 -UseSsl
さて、Send-MailMessage CmdLet に SMTP 認証情報を渡す方法を片付けたら、別の例に焦点を当てましょう。
How To Send Attachment(s) With Email Using PowerShell
時には、追加情報を提供してくれる添付ファイルを電子メールに添付すると非常に便利です。 PowerShell を使用して添付ファイル付きの電子メールを送信する例はすでに使用していますが、ここでは専用の例を見てみましょう。 ここでは、Send-MailMessage CmdLetの-Attachmentsパラメータを使用しています。
注意:この例を動作させるには、これらの変数の値を独自のデータに置き換えてください。
$EmailFrom = "sender’s email address" $EmailTo = "recipient’s email address" $EmailSubject = "Learn PowerShell With Dejan - ImproveScripting.com. (Multiple recipients example)" $EmailBody = "This email has an attachment error log." $SMTPserver= "SMTP server"$EncryptedPasswordFile = "$home\Documents\PSCredential\MailJet.txt"$username="your_user_name" $password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString$credential = New-Object System.Management.Automation.PSCredential($username, $password)Send-MailMessage -ErrorAction Stop -from "$EmailFrom" -to $EmailTo -subject "$EmailSubject" -body "$EmailBody" -SmtpServer "$SMTPserver" -Attachments "$home\Documents\PSlogs\Error_Log.txt" -Priority "Normal" -Credential $credential -Port 587 -UseSsl
Send-MailMessage CmdLetの-Attachmentsパラメータは、入力値として文字列の配列を受け付けるので、同じ電子メールで複数の添付ファイルを送信したい場合は、簡単に行うことができます。
これは2つの添付ファイルを渡す正しい方法です
$Attachments = "$home\Documents\PSlogs\Error_Log.txt", "$home\Documents\PSReports\Excel_report.xls"
そしてこれも同様です
$Attachments = @("$home\Documents\PSlogs\Error_Log.txt", "$home\Documents\PSReports\Excel_report.xls")
しかし、これは間違っています。
$Attachments = "$home\Documents\PSlogs\Error_Log.txt, $home\Documents\PSReports\Excel_report.xls"
PowerShellを使って複数の受信者にメールを送信する方法
PowerShellを使って複数の受信者にメールを送信したい場合、Send-MailMessage CmdLetに文字列の配列を受け付けるパラメータ-Toがあると便利です。 複数のメールアドレスを、カンマで区切られた1つの文字列ではなく、文字列の配列として追加する方法に注意することが重要です。
ここでは、PowerShellを使用して複数の受信者にメールを送信する例を示します:
注意: この例を動作させるには、これらの変数の値を独自のデータに置き換えてください: $EmailFrom, $ToRecipients, $SMTPserver, $username.
$EmailFrom = "sender’s email address" $ToRecipients = "recipient’s email address 1", "recipient’s email address 2", "recipient’s email address 3" $EmailSubject = "Learn PowerShell With Dejan - ImproveScripting.com. (Multiple recipients example)" $EmailBody = "This email has an attachment error log." $SMTPserver= "SMTP server"$EncryptedPasswordFile = "$home\Documents\PSCredential\MailJet.txt"$username="your_user_name" $password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString$credential = New-Object System.Management.Automation.PSCredential($username, $password)Send-MailMessage -ErrorAction Stop -from "$EmailFrom" -to $ToRecipients -subject "$EmailSubject" -body "$EmailBody" -SmtpServer "$SMTPserver" -Attachments "$home\Documents\PSlogs\Error_Log.txt" -Priority "Normal" -Credential $credential -Port 587 -UseSsl
受信者のメールアドレスを文字列配列として正しく渡す場合と、文字列配列ではなく単一の文字列(メールアドレスはカンマで区切られた値ですが、単一の文字列の中にあります)として正しく渡す場合の違いに注目してください。
$ToRecipients = "recipient’s email address 1, recipient’s email address 2, recipient’s email address 3"
複数の受信者にメールを送信するだけでなく、通常のメールでは Cc (Carbon Copy) と Bcc (Blind Carbon Copy) を送信する機能がありますが、そのためにはそれぞれ -Cc と -Bcc (Send-MailMessage CmdLet) というパラメーターを使用し、それぞれにメールアドレスを値として与えています。
How To Send Email With HTML Body Using PowerShell
PowerShellでは、Send-MailMessage CmdLetを使って、メール本文の中にHTMLコンテンツを入れてメールを送信することができます。
- -body パラメータの値は、電子メール クライアントが HTML メールを表示するために、適切にフォーマットされた HTML である必要があります。
- -BodyAsHtml スイッチ パラメータは、-body パラメータに HTML コードがあることを通知するために、Send-MailMessage CmdLet に渡されています。
以下は、電子メールの本文にプレーンテキストではなくHTMLメールを作成するSend-MailMessage CmdLetの呼び出しの例です。
$EmailFrom = "sender’s email address" $EmailTo = "recipient’s email address" $EmailSubject = "Learn PowerShell With Dejan - ImproveScripting.com. HTML Example" $EmailHTMLBody = 'Learn PowerShell With Dejan - ImproveScripting.com'$SMTPserver= "SMTP server"$EncryptedPasswordFile = "$home\Documents\PSCredential\MailJet.txt"$username="your_user_name" $password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString$credential = New-Object System.Management.Automation.PSCredential($username, $password)Send-MailMessage -ErrorAction Stop -from "$EmailFrom" -to "$EmailTo" -subject "$EmailSubject" -body "$EmailHTMLBody" -BodyAsHtml -SmtpServer "$SMTPserver" -Attachments "$home\Documents\PSlogs\Error_Log.txt" -Priority "Normal" -Credential $credential -Port 587 -UseSsl
受信した電子メールの結果です。電子メールの本文には、単なるテキストではなく、このウェブサイトへの HTML リンクがあります。
Gmailを使ってPowerShellからメールを送信する方法。 PowerShellからGmail SMTPサーバーを使用して電子メールを送信する方法
意外な答えが返ってくるかもしれませんが、PowerShellで電子メールを送信する際にGmail SMTPサーバーを使用することはお勧めしません。MailMessage CmdLet.
その理由は、Gmail アカウントの機能を有効にする必要があるという事実です。 “
その理由は、Gmail アカウントの機能である「Enable less secure apps to access Gmail」を有効にする必要があるからです。
System.Net.Mail API
PowerShell を使用して電子メールを送信する代替アプローチの 1 つは、System.Net.Mail 名前空間の .NET クラスを使用することです。
以下に、System.Net.Mail APIを使用した呼び出し例を示します。
注意: この例を動作させるには、これらの変数の値を独自のデータに置き換えてください: $EmailFrom, $EmailTo, $SMTPserver, $username.
$EmailFrom = "sender’s email address”$EmailTo = "recipient’s email address”$EmailSubject = "Learn PowerShell With Dejan - ImproveScripting.com. (System.Net.Mail API Example)”$EmailBody = "This email has as the attachments error log."$SMTPServer = "SMTP server”$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)$SMTPClient.EnableSsl = $true$EncryptedPasswordFile = "$home\Documents\PSCredential\MailJet.txt"$username="your_user_name" $password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($username, $password);$SMTPClient.Send($EmailFrom, $EmailTo, $EmailSubject, $EmailBody)
この例を実際に必要なパラメーターの値に置き換えた後、受信箱に届いたメールは次のとおりです。
私の意見では、System.Net.Mail .NET名前空間クラスを使用することは、.NET開発者にとってより自然なアプローチであり、Send-MailMessage CmdLetを使用することは、よりネイティブなPowerShellのアプローチです。
How To Write Own CmdLet For Sending Emails Using PowerShell
私は Send-Email CmdLet と呼ばれるメール送信機能を提供する独自の PowerShell CmdLet を書きました
この CmdLet は Efficiency Booster PowerShell Project に属しています。
この CmdLet は、Efficiency Booster PowerShell プロジェクトに属しています。このプロジェクトは、私たち IT 個人が日常のタスクをより効率的かつ正確に行うのに役立つさまざまな CmdLets を集めたライブラリです。
Send-Email CmdLet のソース コードは、この zip ファイルからダウンロードできますので、ご自由にダウンロードするか、この記事の下部にあるソース コードをご覧ください。
Send-Email CmdLet は Utils モジュールの一部であり、ソース コードをダウンロードした場合は、 …Documents\WindowsPowerShell\Modules\02utils
この CmdLet は基本的に Send-MailMessage CmdLet のラッパーであり、特に革新的なものではないので、あまり多くは説明しませんが、PowerShell のメール送信機能を自動化や効率化の重要なメカニズムとして使用することは重要です。
INFO: Efficiency BoosterのPowerShellプロジェクトファイルのインストールと設定方法について知りたい方は、以下の記事をご覧ください。 PowerShellのインストールと設定方法。
How To Use Send Email Feature In PowerShell
より効率的に、またはメンテナンスが必要なシステムの概要を把握するために、電子メールを他の PowerShell 機能と組み合わせて使用した例をいくつかご紹介します
Example: サーバーのディスクの空き容量
私は、メンテナンスしているサーバーのディスクの空き容量の概要を知りたいと思いました。 さらに、この CmdLet は週に 1 回実行され、Excel シートとしてレポートを作成し、私の電子メールに送信されるようにスケジュールされています。
この例をさらに拡張して、キャパシティ プランニングに使用したり、データをさらに MS SQL テーブルに送り、MS SQL Reporting Service と組み合わせて、ディスク ストレージの使用状況の傾向をグラフ化し、将来のストレージのアップグレードや拡張を計画することができます。
この PowerShell Cmdlet については、「How To Get Disk Size And Disk Free Space Using PowerShell」という記事をお読みになることをお勧めします。
例。
この目的のために、Windows イベント ログをチェックし、すべてのサーバーでエラーを探す独自の PowerShell CmdLet Get-ErrorFromEventLog を書きました。 このスクリプトは月に一度、メンテナンスの前に実行されるようにスケジュールされており、さらにデータをフィルタリングして見るのが簡単なようにExcelシートを作成します。 最後に、エクセルのレポートが私のメールアドレスに送られてきます。
その意味では、各サーバーにログオンし、各サーバーの Windows イベント ログを手動でチェックするという手作業をしなくて済むので、非常に時間を節約できます。
この2つの例をきっかけに、PowerShellを使ってメールを送信したり、他のPowerShellの機能と組み合わせたりして、素晴らしい可能性を実現していただければと思います。
PowerShell の電子メール送信に関する便利な記事
以下に便利な記事やリソースを紹介します。
- Send-MailMessage
- DE0005: SmtpClient shouldn’t be used
- MailKit
- System.Net.Mail API
- SmtpClient
- NetworkCredential クラス
Send-Email CmdLet – Source Code
DISCLAIMER: Send-Email 機能は Efficiency Booster PowerShell プロジェクトの一部であり、同じプロジェクトの一部である他の CmdLet を利用しています。 そのため、追加のカスタマイズなしでこの機能を動作させるための最良の選択肢は、プロジェクト全体のソース コードをここからダウンロードすることです
インフォ。 すべての PowerShell スクリプターへの最善のアドバイスは、独自の PowerShell 高度関数や CmdLets を書くことを学ぶことです。 カスタムPowerShell CmdLetの作成方法(Step By Step)。 ここでは、PowerShell Add-on Functionを使ってPowerShell関数を高速に書く方法を説明しています。 How To Write Advanced Functions Or CmdLets With PowerShell (Fast).
Send-Email CmdLet全体のソースコードは以下の通りです:
注意:この例を動作させるためには、これらの変数の値を独自のデータに置き換えてください: $EmailFrom, $EmailTo, $SMTPserver, $EncryptedPasswordFile, $username.
<#.SYNOPSISSend email..DESCRIPTIONSend email..PARAMETER AttachmentsEmail attachments. File path to file(s) that will be attachments..PARAMETER PriorityEmail priority. Valid values are: Normal, High, and Low..PARAMETER errorlogWrite to Error log or not. Switch parameter. Error log is in PSLogs Folder of My documents..PARAMETER clientOK - O clientBK - B client.PARAMETER solutionFIN - Financial solution HR - Humane Resource solution.EXAMPLESend-Email -Attachments "$home\Documents\PSlogs\Error_Log.txt" -Priority "Normal" -errorlog -client "Test" -solution "Test" -Verbose.NOTESFunctionName : Send-EmailCreated by : Dejan MladenovicDate Coded : 09/23/2020 15:13:00More info : https://improvescripting.com/send-emails-using-powershell-with-many-examples/.LINK Send-MailMessagehttps://improvescripting.com/send-emails-using-powershell-with-many-examples/#>Function Send-Email {param ( ]$Attachments, $Priority = "Normal", $errorlog, $client, $solution)BEGIN { }PROCESS { try { Write-Verbose "Sending email..." if( $client -eq "OK" -and $solution -eq "FIN") { ##REPLACE THIS VALUE!!! $EmailFrom = "your_email" ##REPLACE THIS VALUE!!! $EmailTo = "your_email" $EmailSubject = "Report from Financial solution - OK client." $EmailBody = "This email has as attachments error log and report file from Financial Solution - OK client." ##REPLACE THIS VALUE!!! $SMTPserver= "your_SMTP_server" ##REPLACE THIS VALUE!!! $EncryptedPasswordFile = "$home\Documents\PSCredential\MailJet.txt" ##REPLACE THIS VALUE!!! $username="your_user_name" $password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString $credential = New-Object System.Management.Automation.PSCredential($username, $password) ##Change this as splatting syntax in Send-MailMessage CmdLet Send-MailMessage -ErrorAction Stop -from "$EmailFrom" -to "$EmailTo" -subject "$EmailSubject" -body "$EmailBody" -SmtpServer "$SMTPserver" -Attachments $Attachments -Priority $Priority -Credential $credential -Port 587 } elseif ( $client -eq "Test" -and $solution -eq "Test" ) { ##REPLACE THIS VALUE!!! $EmailFrom = "your_email" ##REPLACE THIS VALUE!!! $EmailTo = "your_email" $EmailSubject = "Test of Send-Email cmdlet" $EmailBody = "This is test email." ##REPLACE THIS VALUE!!! $SMTPserver= "your_SMTP_server" ##REPLACE THIS VALUE!!! $EncryptedPasswordFile = "$home\Documents\PSCredential\MailJet.txt" ##REPLACE THIS VALUE!!! $username="your_user_name" $password = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString $credential = New-Object System.Management.Automation.PSCredential($username, $password) ##Change this as splatting syntax in Send-MailMessage CmdLet Send-MailMessage -ErrorAction Stop -from "$EmailFrom" -to "$EmailTo" -subject "$EmailSubject" -body "$EmailBody" -SmtpServer "$SMTPserver" -Attachments $Attachments -Priority $Priority -Credential $credential -Port 587 } Write-Verbose "Email sent." } catch { Write-Warning "There was a problem with sending email, check error log. Value of error is: $_" if ( $errorlog ) { $errormsg = $_.ToString() $exception = $_.Exception $stacktrace = $_.ScriptStackTrace $failingline = $_.InvocationInfo.Line $positionmsg = $_.InvocationInfo.PositionMessage $pscommandpath = $_.InvocationInfo.PSCommandPath $failinglinenumber = $_.InvocationInfo.ScriptLineNumber $scriptname = $_.InvocationInfo.ScriptName Write-Verbose "Start writing to Error log." Write-ErrorLog -hostname "Send Email was failing." -errormsg $errormsg -exception $exception -scriptname $scriptname -failinglinenumber $failinglinenumber -failingline $failingline -pscommandpath $pscommandpath -positionmsg $pscommandpath -stacktrace $stacktrace Write-Verbose "Finish writing to Error log." } }}END { }}#Send-Email -Attachments "$home\Documents\PSlogs\Error_Log.txt" -Priority "Normal" -errorlog -client "Test" -solution "Test" -Verbose
。