ネットワークトラブルで大量(数十万件)のエラーメールが管理者アドレスに届き、グループウェアWebメールが受信できない。メールデータを取捨選択して整理できるか new!

ネットワークトラブルで大量(数十万件)のエラーメールが管理者アドレスに届き、グループウェアWebメールが受信できない。メールデータを取捨選択して整理できるか、という質問を受けたことがあります。

まず前提として、いったん特定アカウントのメールボックスに“着信済み”となったメールについて、E-Post側で「後から受信フィルタのように自動で振り分け・削除」する機能は用意されていません。
E-Postのメールフィルタ機能(【mail.dat】等)はSMTP受信時に動作するものであり、到達後のメールをその場で再判定して制御する用途に使うことはできません。
ただし、E-Postのメールボックスはメールデータがファイルとして保存される方式のため、OS側の操作(検索→移動→削除)で「整理」することは可能です。

・POP3形式/IMAP4形式共にメールボックスでは、拡張子.MSG(1メール=1ファイル)で保管されます。(※Journal Optionでは拡張子.MSGと拡張子.RCPの(1メール=2ファイル)セット保存になります。これはBCCを判定する目的で意図的に残してあるものです。)
・IMAP4形式のメールボックスはフォルダの位置が異なります。くわしくは下記記事参照。大量のIMAPメールは、クライアント側が読み込みしきれずエラーになる例も報告されています。そのため、グループウェアWebメールが処理できないほど溜まっている場合は、サーバ上でメールデータファイルを“退避”させて総数を減らすのが現実的です。
(関連FAQ)
方式の違いによるメールボックスフォルダの作成位置について
IMAP使用時のメールボックスフォルダと「POP3無効」チェックボックスの関係について
IMAPデータファイルの基本的な構造について

安全な進め方
1.増え続ける状態ならまず止血する
原因が継続中だと整理しても追いつかないため、可能なら先にネットワーク復旧/誤送信停止などで、これ以上増えない状態を作ります。

2.対象メールボックスをバックアップ
対象アカウントのメールボックスフォルダを丸ごと別領域にコピーしてからの作業を推奨します(誤削除対策)。

3..MSGファイルを検索して、該当ファイルを退避フォルダへ移動する
.MSGファイルを退避させ総数を減らすことにより、まずはWebメールが受信できる状態になるかの確認を行います。

整理方法の例
A.grep等のツールが利用できる場合(推奨)
E-Postのメールデータ(.MSG)は基本的に「1メール=1ファイル」です。
そのため、grep等の検索ツールやgrep機能をもつエディタでヘッダ文字列をキーに該当メールを抽出し、ファイルを移動/削除することで整理できます。
例:Fromヘッダで該当メールを抽出してファイル一覧を作成する
grep -l -F "From: xxxx <xxxx@xxxx.xxx>" *.MSG > list.txt
作成された list.txt を元に、move/del 等で一括処理します。
※Journal Optionで .RCP が併存している環境では、.MSG と .RCP が同番号の対になっているため、移動・削除は 対で行うようにしてください。方法については下記参照。
※JIS(iso-2022-j)やUTF-8の場合は、エンコード文字列で検索する必要があります。

B.findstrコマンドを使う方法
Windows Serverに備わっているコマンドのうち、findstrをコマンドラインより実行する方法です。 エラーメール(バウンス系)は、件名が日本語MIMEエンコードで読みにくいことがあるため、From:やReturn-Path:などASCIIで表現され検索しやすいヘッダをキーにします
例:.MSG から From を探してヒットしたファイル一覧を作る
findstr ⁄M ⁄C:"From: xxxx <xxxx@xxxx.xxx>" *.MSG > list.txt
list.txt ができたら、それを使って move / del のバッチで一括処理します(まずは削除ではなく退避用フォルダへ移動推奨)。

C.PowerShellで“対ファイル”も含めて安全に移動(Journal Option想定)
Journal Optionの場合は.MSGと.RCPが同番号で1組なので、.RCP側を検索キーにして、該当番号の.MSG/.RCPをまとめて退避します。
例:.RCP内の Return-path をキーに振り分け、退避

$src = "C:\mail\INBOX\...\INBOX"  ←.MSGと.RCPがある対象フォルダ
$dest = "C:\mail\INBOX\...\_evac"  ←退避先フォルダ
$target = "user1@test-sample.jp"  ←検索したいReturn-pathの値(完全一致)

New-Item -ItemType Directory -Force -Path $dest | Out-Null  ←退避先フォルダを作成(既にあってもよい)

Get-ChildItem -Path $src -Filter "*.RCP" -File |  ←Return-pathが一致するRCPを検索し、同じIDの.MSGと.RCPを退避
Select-String -Pattern ("^Return-path:\s*" + [regex]::Escape($target) + "\s*$") -List |
ForEach-Object {
$base = [IO.Path]::GetFileNameWithoutExtension($_.Path)   ←ファイル名からID部分のみ取り出す 例:123456-000000
$id = $base.Split(’-’)[0]                   ←“-”で分割し、共通IDを得る 例:123456
Get-ChildItem $src -Filter "$id-*.MSG" | Move-Item -Destination $dest  ←上記で得た共通IDに一致する.MSGファイルを探す
Get-ChildItem $src -Filter "$id-*.RCP" | Move-Item -Destination $dest  ←上記で得た共通IDに一致する.RCPファイルを探す
}
まずは退避フォルダ(例:_evac)に移動してWebメールが復旧するか確認 → 問題なければ、退避フォルダ(例:_evac)内をさらに条件で細かく仕分け/不要分を削除、の順が安全です。