0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【PowerShell】Outlookのmsgファイルを変換

Last updated at Posted at 2025-03-25

【PowerShell】

■はじめに

  • この記事は?
    OutlookのmsgファイルをテキストとCSVに変換するスクリプトを解説

■スクリプトの概要

  • 何をするスクリプトか?
     - Outlookからコピーした.msgファイルの入ったディレクトリを指定し、
      ディレクトリ内のすべての.msgファイルを.txtファイルに変換
     - 変換したすべての.txtファイルからサマリーのcsvファイルを作成
  • どんな場面で役に立つか?
     - 大量のメールから、必要な情報を検索・抽出

■動作確認環境

  • Windows 11 Pro 24H2 (OS ビルド 26100.3476)
  • PowerShell 5.1.26100.2161
  • Outlook 2502 (ビルド 18526.20168)

■スクリプトのソースコード

outlook-msg-change.ps1
# Read-Hostのメッセージにカラーを付与するための関数(確認用)
function Set-Conf {
    param(
        [Parameter(Position = 0, ValueFromPipeline = $true)]
        [string]$msg,
        [string]$BackgroundColor = "DarkGray",
        [string]$ForegroundColor = "White"
    )

    Write-Host -BackgroundColor $BackgroundColor -ForegroundColor $ForegroundColor -NoNewline $msg
    return Read-Host
}

# Read-Hostのメッセージにカラーを付与するための関数(出力用)
function Set-Out {
    param(
        [Parameter(Position = 0, ValueFromPipeline = $true)]
        [string]$msg,
        [string]$BackgroundColor = "DarkBlue",
        [string]$ForegroundColor = "White"
    )

    Write-Host -BackgroundColor $BackgroundColor -ForegroundColor $ForegroundColor -NoNewline $msg
    return Read-Host
}

# Read-Hostのメッセージにカラーを付与するための関数(エラー出力用)
function Set-Err {
    param(
        [Parameter(Position = 0, ValueFromPipeline = $true)]
        [string]$msg,
        [string]$BackgroundColor = "DarkRed",
        [string]$ForegroundColor = "White"
    )

    Write-Host -BackgroundColor $BackgroundColor -ForegroundColor $ForegroundColor -NoNewline $msg
    return Read-Host
}

Set-Out "<処理開始>指定したディレクトリの .msgファイルをテキストファイルに変換します。Enterを押してください。"

$srcDir = Set-Conf "<1>.msgファイルが格納されているディレクトリを入力(省略時はカレントディレクトリ):"
$destDir = Set-Conf "<2>変換後のテキストファイルを保存するディレクトリを入力(省略時はカレントディレクトリのmsg_txtフォルダ):"

# ディレクトリ存在確認・設定
if ($srcDir -eq "") {
    $srcDir = Split-Path $myInvocation.MyCommand.Path -Parent
}
if (!(Test-Path $srcDir)) {
    Set-Err "▶ 【変換元ディレクトリが存在しません。処理を終了します。Enterを押してください。】"
    return
} else {
    Set-Out "▶ 【変換元ディレクトリ: $srcDir を確認しました。Enterを押してください。】"
}

if ($destDir -eq "") {
    $destDir = Join-Path (Split-Path $myInvocation.MyCommand.Path -Parent) "msg_txt"
}
if (!(Test-Path $destDir)) {
    New-Item -Path $destDir -ItemType Directory | Out-Null
    Set-Out "▶ 【変換後ディレクトリ: $destDir を作成しました。Enterを押してください。】"
} else {
    Set-Out "▶ 【変換後ディレクトリ: $destDir を確認しました。Enterを押してください。】"
}

# 再帰的に処理するかどうかの確認
$YesNo = Set-Conf "サブフォルダも含めて再帰的に処理しますか?[Y(y)/N(n)]"
if ($YesNo -eq "Y") {
    $RecurseOption = $true
} else {
    $RecurseOption = $false
}

# CSV出力準備
$csvPath = Join-Path $destDir "mail_summary.csv"
"件名,差出人,宛先,CC,受信日時,本文" | Out-File -Encoding UTF8 $csvPath

# 変換処理開始
$outlook = New-Object -ComObject Outlook.Application

Get-ChildItem -Path "$srcDir\*.msg" -Recurse:$RecurseOption | ForEach-Object {
    $msg = $outlook.Session.OpenSharedItem($_.FullName)

    $text = @"
件名: $($msg.Subject)
差出人: $($msg.SenderName)
宛先: $($msg.To)
CC: $($msg.CC)
受信日時: $($msg.ReceivedTime)

本文:
$($msg.Body)
"@

    $outFile = Join-Path $destDir ($_.BaseName + ".txt")
    $text | Out-File -Encoding UTF8 $outFile

    # CSV用データ処理
    $subject = '"' + $msg.Subject.Replace('"','""') + '"'
    $sender = '"' + $msg.SenderName.Replace('"','""') + '"'
    $to = '"' + $msg.To.Replace('"','""') + '"'
    $cc = '"' + $msg.CC.Replace('"','""') + '"'
    $received = '"' + $msg.ReceivedTime + '"'
    $body = '"' + $msg.Body.Replace('"','""').Replace("`r`n", "<改行>") + '"'

    "$subject,$sender,$to,$cc,$received,$body" | Out-File -Encoding UTF8 -Append $csvPath

    Write-Host "変換済: $($_.Name)"

    # 各メールのCOMオブジェクトを解放する(重要)
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($msg) | Out-Null
}

Start-Sleep -Milliseconds 5000  # メール処理後5秒待機

# Outlookオブジェクトの終了処理を安全に行う(Quitしない)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Null

$outlook = $null
$msg = $null

# ガベージコレクションを明示的に行い、メモリを解放
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

Set-Out "すべての変換とCSVファイルへの出力が完了しました。Enterを押して終了してください。"
Read-Host
0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?