border not found

分野・領域などを問わず、何でも綴る雑記帳

Office365 の共有メールボックスから Powershell で送信する

はじめに

Office365 のアカウントから Powershell を使ってメールを送信する記事は多く見つかるのですが、共有メールボックスから送信する記事は見つからなかったので作成しました。 ついでに設定を Script に直に記述しなくても簡単に送信元を切り替えられるよう、設定ファイルを XML で外だししました。(こっちがメインになってしまったかも)

ポイントは下記2点です。

  • 認証するユーザと送信元アドレスを個別設定している
  • 前述の設定ファイルの分離

分離された設定ファイルはデフォルト値を予め設定しているので、引数 (ConfigXml オプション) が指定されていない場合は Script と同一ディレクトリの XML ファイルを呼びに行きます。

余談ですが、最初 Qiita に投稿するつもりで書いていたのですが、はてなブログに載せたらどう見えるかなと思ってこちらでも投稿してみました。 はてなブログでもコードをハイライトできることを発見し、深夜に一人「できる、できるぞー」と心の中で叫んでしまいましたw Qiita で予約投稿できないのが、ちょっと残念。。。

前提条件

  • ExecutionPolicy が RemoteSigned になっている
  • 送信元となる Script 実行ホストから Port587 で Office365 の SMTP サーバに接続可能な状態
  • Exchange Online 側で SMTP が有効になっている

動作確認済み環境

OS $PSVersionTable の PSVersion
Windows Server 2012R2 4.0

実行例

設定ファイルを指定しない場合 ( デフォルト設定の XML を呼び出し )

PS C:\Windows\system32>  C:\Script\SendEmailScript.ps1

設定ファイルを指定する場合 ( 指定の XML を呼び出し )

PS C:\Windows\system32>  C:\Script\SendEmailScript.ps1 -ConfigXml "C:\Script\SendEmailScript1.xml"

Powershell Script

<#
    Script Name                : Send E-Mail Script
    Script File                : C:\Script\SendEmailScript\SendEmailScript.ps1
    Default Configuration File : C:\Script\SendEmailScript\SendEmailScript.xml
    Script Version             : 1.0
    ExectionPolicy             : RemoteSigned
    LastUpdate                 : 2019/01/27

    History :
      2019/01/27 Create New
#>

Param(
    [Parameter(Mandatory = $false)]
    [ValidateNotNullOrEmpty()]
    [String] $ConfigXml = ((Split-Path $myInvocation.MyCommand.path) + '\SendEmailScript.xml')
)

# Check Configuration File
If (!(Test-Path -Path $ConfigXml)) {
    Write-Host ("Configuration file not found.")
    Exit
}

# SendEmail Function
function EmailPreparation {
    # Read configuration file
    foreach ($Param in ([xml](Get-Content $ConfigXml)).Config) {
        # Set Cred Info
        $CredUser           = ($Param.Cred.CredUser)
        $CredPwd            = ($Param.Cred.CredPwd)

        # Set Mail Setting
        $SmtpServer         = ($Param.Mail.SmtpServer)
        $SmtpPort           = ($Param.Mail.SmtpPort)
        $FromAddr           = ($Param.Mail.FromAddr)
        $DestAddr           = ($Param.Mail.DestAddr)
        $MailSubject        = ((Get-Date -format 'yyyyMMdd-HHmmdd') + " " + ($Param.Mail.MailSubject))
        $MailBodyFilePath   = (Get-Content -Encoding Ascii ($Param.Mail.MailBodyFilePath) -Raw)
    }

    # Create Stmp Client
    $SmtpClient             = New-Object Net.Mail.SmtpClient($SmtpServer,[int]$SmtpPort)
    $SmtpClient.EnableSsl   = $true
    $SmtpClient.Credentials = New-Object System.Net.NetworkCredential($CredUser, $CredPwd)

    # Send Mail Processing
    $SmtpClient.Send($FromAddr, $DestAddr, $MailSubject, $MailBodyFilePath)
    $SmtpClient.Dispose()

}

# Write Error Log Function
function WriteErrorLog ($ErrorMsg) {
    foreach ($Param in ([xml](Get-Content $ConfigXml)).Config) {
        # Set Env
        $ErrorLogDirPath    = ($Param.Env.ErrorLogDirPath)
        $ErrorLogFileName   = ($Param.Env.ErrorLogFileName)
        $ErrorLog           = ($ErrorLogDirPath + "\" + $ErrorLogFileName)
    }
    If (!(Test-Path -Path $ErrorLogDirPath)){
        New-Item -Path $ErrorLogDirPath -ItemType Directory -Force
        If (!(Test-Path -Path $ErrorLog)){
            New-Item -Path $ErrorLog -ItemType File -Force
        }
    }
    Add-Content $ErrorLog ((Get-Date -Format "yyyy/MM/dd HH:mm:dd:ss") + " : " + $ErrorMsg)
}


# Send Email
try{
    EmailPreparation
}
catch{
    WriteErrorLog("Failed to send e-mail.")
}

XML

設定する項目は以下の通りです。サンプル XML を改版する際の参考にしてください。

設定項目 設定内容 備考
ErrorLogDirPath ログファイル格納先のパス
ErrorLogFileName ログファイルのファイル名
CredUser 認証ユーザ
CredPwd 認証ユーザのパスワード
SmtpServer SMTP サーバ IP か FQDN で指定
SmtpPort SMTP のポート番号 OB25P で 587 を指定するケースが多いはず
FromAddr 送信者のメールアドレス
DestAddr 宛先のメールアドレス 複数の宛先にする場合はコンマで区切る
MailSubject メールのタイトルに入れる定型文 不要なら空欄で OK
MailBodyFilePath メール本文に入れるテキストファイルのパス 下記サンプル XML では hosts ファイルを指定しています
<?xml version="1.0"?>
<Config>
  <Env>
    <ErrorLogDirPath>C:\Scripts\Logs</ErrorLogDirPath>
    <ErrorLogFileName>SendEmailError.log</ErrorLogFileName>
  </Env>
  <Cred>
    <CredUser>user01@hogehoge.com</CredUser>
    <CredPwd>password</CredPwd>
  </Cred>
  <Mail>
    <SmtpServer>smtp.office365.com</SmtpServer>
    <SmtpPort>587</SmtpPort>
    <FromAddr>info@hogehoge.com</FromAddr>
    <DestAddr>user01@foofoo.net,user02@foofoo.net</DestAddr>
    <MailSubject>Send e-mail test</MailSubject>
    <MailBodyFilePath>C:\Windows\System32\Drivers\etc\hosts</MailBodyFilePath>
  </Mail>
</Config>