PowerShell

winmail.datから添付ファイルを取り出すPowerShellコード

Outlook以外のメールクライアントを使用しているのであれば、一度は目にしたことがある方も多いであろう「winmail.dat」。

今日久々にこのファイルを取り扱う機会があったので、折角なのでwinmail.datから添付ファイルを取り出すスクリプトを書いてみました。

winmail.datとは?

winmail.datとは、Microsoftのサポートページに詳しい説明が記載されています。

一般的に、TNEF の使用は Microsoft Outlook リッチ テキスト形式 (RTF) と呼ばれる Outlook の設定の影響を受けます。 リッチ テキスト形式と TNEF は全く同じではありませんが、密接に関連しています。

TNEF でエンコードされたメッセージには、メッセージのプレーン テキスト版と、オリジナル メッセージのその他のさまざまな部分を「パッケージ化する」バイナリ アタッチメントが含まれています。 ほとんどの場合において、バイナリ アタッチメントは Winmail.dat の名前が付けられており、次の情報が含まれていることがあります。

https://support.microsoft.com/ja-jp/help/290809/how-e-mail-message-formats-affect-internet-e-mail-messages-in-outlook より

TNEF は、トランスポート ニュートラル カプセル化形式、Outlook リッチ テキスト形式、または Exchange リッチ テキスト形式とも呼ばれ、MAPI メッセージ プロパティをカプセル化する Microsoft 固有の形式です。 Outlook のすべてのバージョンが TNEF を完全にサポートします。 Web 上の Outlook (旧称 Outlook Web App) は TNEF を MAPI に変換し、書式設定されたメッセージを表示します。 TNEF をサポートしていないその他の電子メールクライアントでは、通常、TNEF 形式のメッセージが Winmail.dat または Win.ini 添付ファイル付きのプレーンテキストメッセージとして表示されます。

https://docs.microsoft.com/ja-jp/exchange/mail-flow/content-conversion/tnef-conversion より

要するに、Outlookからリッチテキスト形式のメールを送信したときに、TNEFをサポートしていないメールクライアントで受信すると、「winmail.dat」という名前の添付ファイルとして、メールの中身がまとめられてしまうわけですね。

TNEF対応のMimeKit

この「winmail.dat」を処理するにあたり、メール送信でお馴染みのMimeKitのドキュメントを見てみると、ちゃんとTNEFに対応していることが分かります。

今回はこのMimeKitを使って、winmail.datから添付ファイルを取り出してみたいと思います。

winmail.datから添付ファイルを取り出すC#コード

PowerShellでスクリプトを書く前に、まずは簡単にC#でコードを書いてみます。
MimeKitは事前にNuGetでインストールしておいてください。

/*
 * [winmail.dat]から添付ファイルを取り出すC#コード
 * ※MimeKit使用
 */
using System;
using System.IO;
using MimeKit;
using MimeKit.Tnef;

namespace AttachmentsFromTnef
{
  class Program
  {
    public static void Main(string[] args)
    {
      var tnef = new TnefPart();
      tnef.Content = new MimeContent(File.OpenRead(@"C:\Test\winmail.dat"), ContentEncoding.Binary);
      foreach (var atth in tnef.ExtractAttachments())
      {
        if (atth.IsAttachment == true)
        {
          var part = (MimePart)atth;
          using (var stm = File.Create(Path.Combine(@"C:\Test", part.FileName)))
          {
            part.Content.DecodeTo(stm);
          }
        }
      }
      Console.Write("Press any key to continue.");
      Console.ReadKey(true);
    }
  }
}

参考資料が乏しく、インテリセンスを活用しながら適当に書きましたが、大体上記のような感じでコードが書けました。

あとはこれをPowerShellに書き換えていくだけです。

winmail.datから添付ファイルを取り出すPowerShellコード

$winmail_path = "C:\Test\winmail2.dat" #[winmail.dat]のパス

[void][System.Reflection.Assembly]::LoadFile("C:\System\MimeKit\MimeKit.dll") #DLL読み込み
$tnef = New-Object MimeKit.Tnef.TnefPart
$tnef.Content = New-Object MimeKit.MimeContent([System.IO.File]::OpenRead($winmail_path), [MimeKit.ContentEncoding]::Binary)

#[winmail.dat]と同じ場所に添付ファイル出力
foreach($atth in $tnef.ExtractAttachments()){
  if($atth.IsAttachment -eq $true){
    try{
      $part = [MimeKit.MimePart]$atth
      $output_path = [System.IO.Path]::Combine([System.IO.Path]::GetDirectoryName($winmail_path), $part.FileName)
      $stm = New-Object -TypeName System.IO.FileStream -ArgumentList $output_path, Create
      $part.Content.DecodeTo($stm)
    }finally{
      $stm.Dispose()
    }
  }
}

C#と大体同じですね!
MimeKitのおかげで簡単に処理が書けました。

というわけで、winmail.datを処理するスクリプトを書いてみたわけですが、最近このファイルを見かける回数も減りましたし、需要はあまりないのではないかと思います

ましてや、「Winmail Opener」を使えば簡単にファイルを取り出せるので、大量にwinmail.datを処理する必要があるときくらいしか出番が無いスクリプトでしょう。

ただ、“MimeKitを使えばwinmail.datも処理できる”ことだけでも頭の片隅に置いておけば、いつか役立つときがくるかもしれません。

関連記事

  1. Office関連

    PowerShellからNetOfficeを使ってExcelを操作する方法

    先日、Excel MVPの伊藤さんがPowerShellからExcel…

  2. リボン関連

    PowerShellからリボンUIを呼ぶ方法

    下記記事で簡易的なUIとして手軽なHTAを使いました。…

  3. PowerShell

    [PowerShell]MailKitを使ってサーバー上のメールを確認する方法(POP3)

    先日からMailKitを使ってメール送信を行うPowerShellのコ…

  4. VBScript

    [クライアント管理]WMI Explorerの紹介

    端末のハードウェア情報やインストールされているソフトウェアなどを調べる…

  5. PowerShell

    [PowerShell]メール送信用関数

    PowerShellを使ってメール送信する機会が増えてきたので、処理を…

  6. Windows 10

    ストアアプリを起動するPowerShellコード

    ストアアプリ(UWPアプリ)は実行ファイルをダブルクリックする等して直…

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

最近の記事

アーカイブ

RapidSSL_SEAL-90x50
PAGE TOP