PowerShellでOutlookにアクセスする

MSのメールクライアントと言えばOutlookですが、メールを他のソフトウェアから扱おうとするとちょっと厄介ですね。
今回はPowerShellでメールをエクスポートする方法を試したいと思います。

もくじ:

はじめに

OutlookでExchangeのメールをエクスポートしたいときって、何がベストプラクティスなんでしょうね。普通にエクスポート機能を使うとPSTファイル(*.pst)に出力できますが、MS独自仕様なので一筋縄では扱えません。テキストエディタで開いたり、バイナリモードで開いても内容が読めない、ということです。

単にメールなどのアイテムだけではなく、フォルダ構造や属性などのメタデータも記録していますし、長い歴史のなかで互換性を保つために独自の拡張が必要だった経緯を考えると、無理からぬことではあります。

ネットで調べると、一応MSはPSTの仕様を公開しているようですし、C++のSDKやらPythonでも有志がSDKのラッパを作っているようです。しかしいずれも一様に面倒臭そう。

今回は、できるだけシンプルかつMSオフィシャルなやり方を目指して、COMオブジェクトを使うことにしました。調べてみるとVBAの実行例が多いようですね。

前提

今回のスクリプトは、OutlookのCOMオブジェクトに依存しています。
つまりはOutlookがインストールされており、メールアカウントがセットアップされていてメールが閲覧できる(またはPSTファイルからインポートされている)PCで実行する必要があります。

また、COMオブジェクト経由でOutlookの機能にアクセスするには、Officeのインストールオプションとして「.NETプログラミングサポート」を有効化する必要があります。
デフォルトで有効化されているかどうか確認していませんが、いつものコンパネ「プログラムと機能」からOfficeのインストーラを立ち上げれば構成できます。

スクリプト

今回のスクリプトです。検証した環境はWindows 10 Pro + Outlook 2016です。

ローカルの保存先ディレクトリパスを$dstDirに指定して実行します。
アカウントやメールフォルダごとにディレクトリを作成し、その中にメッセージをファイルとして書き出していきます。

環境によっては、アクセスを許可するかをたずねるメッセージボックスがポップアップする場合もあるようです。

以下、スクリプトの詳細を説明しておきます。

PowerShellでメールを保存する

今回のスクリプトの目的は、Outlookが保持しているアカウントやフォルダ毎にローカルのファイルシステムにディレクトリ階層を作り、メールの本文を宛先や送信時刻などのメタデータとともに保存することです。

COMオブジェクトを作成しているのは、上のスクリプト終わりのほう(下記の部分)。オブジェクト名や名前空間を取得するところは共通的な処理なので、ググると他にも色々なサンプルがヒットすると思います。

今回は、基本的にFoldersプロパティを再帰的に辿って、Itemsプロパティごとに処理していきます。

受信トレイのみ、とか特定のアカウント名だけ、などフィルタすることもできます。

階層を辿ってメールに行き着けば、メール1通毎にディレクトリを作成し、データをまとめたJSONファイルを作成します。

メールフォルダの取得

Outlookを開いたときにツリー表示されるフォルダの部分は、Foldersプロパティで取得できます。今回は、メール以外の、例えばタスクや連絡先といったフォルダは不要なので、MailItemオブジェクトを表す「0」のみを処理します。

メッセージと添付ファイルの取得

Outlook、というかExchangeはスケジュールや連絡先など様々な種類のオブジェクトを使っていますが、今回欲しいのはメールのメッセージのみ。
すでにフォルダの種別で絞り込んでいますが、ここではさらにClassプロパティの値でメッセージを抽出します。

メッセージのオブジェクトを取り出せば、あとは各プロパティで本文や宛先などのデータを取得できます。今回は一旦、連想配列に複製し、JSONファイルとして書き出します。

また、メッセージに添付ファイルが付いている場合はAttachmentsプロパティのSaveAsFile()メソッドを使って保存できます。

コメント

  1. より:

    質問です。
    MAPIを使って、outlookアカウントに送信される添付ファイルをローカルに保存するpowershellのスクリプトを作成しました。
    https://kapibara-sos.net/archives/394
    こちらを参考しています。

    powershellを作成後、.ps1ファイルを直接実行すると添付ファイルの保存ができますが
    .ps1ファイルをwindowsのタスクスケジューラで実行すると、MAPIのインスタンスが作成されません。

    試したこと:
    ・タスクスケジューラの実行権限を最上に権限にする
    ・.ps1ファイルをタスクスケジューラで実行する際には、powershellの実行権限をBypassにしている。

    よろしくお願いいたします。

    返信

    • usta より:

      タスクスケジューラでpowershellを使うとパスの指定が面倒なので、あまり私は利用しません。(バッチファイルを作成している)
      どうしても、ということであればこちらが参考になります。
      https://www.atmarkit.co.jp/ait/articles/1412/03/news125.html

      あとは実行時のユーザをSystem (NT AUTHORITY\System)にして試してみるか、くらいしか思いつきません。