概要
- .NET Framework の SmtpClient クラスを使ってメールを送信できる
- 認証が必要なときは、NetworkCredential を SmtpClient#Credentials に設定する
- SSL が必要か、ポート番号はいくつか、などはプロバイダーの資料を要確認
SmtpClient クラス
PowerShell で電子メールを SMTP で送るときは、.NET Framework の標準ライブラリに含まれている System.Net.Mail.SmtpClient クラスを使うのでお決まりっぽい。
最低限このクラスを使うだけでいいし、バージョンの縛り(2以降)も厳しくないし。
使い方はこんな感じ。
$sc = New-Object Net.Mail.SmtpClient("smtp.example.com") $sc.Send("sender@example.com", "receiver@example.com", "Subject", "Message Body")
Windows Script で CDO を使うのに長ーい呪文が必要なのと比べると、実に簡単でわかりやすい!
でも SMTP で認証が必要がな時はどうする? ユーザー名とパスワードを設定するプロパティがあるのかなと思ったら、なかった。
SMTP の認証方法について
そもそもSMTP というプロトコル(最初の RFC は 1982 年)は個人認証のための仕組みを持っていなかったところ、電子メールの普及に伴って必要性が生じたため、後付けで POP before SMTP や、 SMTP Authentication という方法が考案されたという。
電子メールというと、最近は携帯電話のメールと gmail と Exchange しか使っていなかったので、このあたりの事情に疎くなっていた。
こういった背景があるためか、それとも再利用性を高めるためかわからないけど、.NET Framework では、SmtpClient クラスにユーザー名とかパスワードをプロパティで直接設定できるようにはなっていない。
そのかわり、ユーザー名やパスワードを?ICredentialsByHost という型にカプセル化して、SmtpClient#Credentials プロパティに設定する仕組みになっている。
SMTP Authentication 用にこのオブジェクトを作るには、System.Net.NetworkCredential クラスを使えばいい。こんな感じ。
$sc.Credentials = New-Object Net.NetworkCredential(username, password)
msdn 読むと、NetworkCredential クラスは別に SMTP Authentication 専用ではなく、ベーシック認証とか NTLM 認証とか、パスワードに基づく認証全般に使われるっぽい。
ということは、このクラスは単なる文字列のコンテナで、実際の認証の仕組みは SmtpClient 側で実装されているのかな。
コードの例
$username = "username" $password = "password" $myhost = "smtp.example.com" $port = 587 $from = "from@example.com" $recipients = "recipient@example.com" $subject = "test mail by powershell" $body = "hello?`r`nare you here?" $sc = New-Object Net.Mail.SmtpClient $sc.Host = $myhost $sc.Port = $port $sc.EnableSsl = $true $sc.Credentials = New-Object Net.NetworkCredential $sc.Credentials.UserName = $username $sc.Credentials.password = $password $c.send($from, $recipients, $subject, $body)
プロバイダー毎の設定
サーバーによっては SMTP のために SSL を使う必要があって、そんな場合は SmtpClient#Enablessl プロパティを true に設定する。SSL の必要がなかったら false(規定値)。
例えば gmail の場合は SSL が必要。うちでインターネット接続のために使っている @nifty は SSL 不要っぽい。
gmail のヘルプページには smtp のポートが TLS と SSL の2種類記載されていて、どう違うのかよくわからない。SmtpClient のプロパティに渡すポート番号は、TLS の 587 でないと動かなかった。
参考文献
- SmtpClientクラスを使用したSMTP認証メール送信に失敗する。 ? Insider.NET ? @IT <http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=35369&forum=7>
- その他のメール クライアントの設定 – Gmail ヘルプ <http://mail.google.com/support/bin/answer.py?hl=jp&answer=13287>