【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