<#
簡易MIMEメール展開スクリプト
cURLで送信したEMLファイルを展開する。
検証環境やクローズド環境で使用して下さい。
MIT License
Copyright (c) 2026 yoshio (zo3.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction...
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND...
#>
param(
[string]$EmlFile,
[string]$OutDir = ".\out"
)
$CRLF = "`r`n"
# 出力先
New-Item -ItemType Directory -Force -Path $OutDir | Out-Null
# 全文取得
$content = Get-Content -Raw -Path $EmlFile
# ヘッダとボディ分離
$parts = $content -split "$CRLF$CRLF", 2
$headers = $parts[0]
$body = $parts[1]
# boundary取得
$boundary = $null
if ( $headers -match 'boundary="([^"]+)"') {
$boundary = $matches[1]
}
# RFC2231 decode
function Decode-RFC2231($s) {
if ($s -match "UTF-8''(.+)") {
$enc = $matches[1]
$bytes = @()
for ($i = 0; $i -lt $enc.Length; ) {
if ($enc[$i] -eq '%') {
$bytes += [Convert]::ToByte($enc.Substring($i + 1, 2), 16)
$i += 3
}
else {
$bytes += [byte][char]$enc[$i]
$i++
}
}
return [System.Text.Encoding]::UTF8.GetString($bytes)
}
return $s
}
# Base64 decode
function Decode-Base64($text) {
$clean = ($text -replace '\s', '')
return [Convert]::FromBase64String($clean)
}
if ( $null -eq $boundary ) {
# 単一パート 本文のみ
$textPath = Join-Path $OutDir "body.txt"
Set-Content -Path $textPath -Value $body -Encoding UTF8
}
else {
# マルチパート分解
$sections = $body -split "--$boundary"
foreach ($sec in $sections) {
if ($sec -match "--\s*$") { continue }
if ($sec.Trim() -eq "") { continue }
$sp = $sec -split "$CRLF$CRLF", 2
if ( $sp.Count -lt 2 ) { continue }
$h = $sp[0]
$b = $sp[1].Trim()
# 添付判定
if ( -not ( $h -match "Content-Disposition: attachment" ) ) {
# 本文
$textPath = Join-Path $OutDir "body.txt"
Set-Content -Path $textPath -Value $b -Encoding UTF8
}
else {
# filename取得(優先:filename*)
$filename = "unknown.bin"
if ($h -match "filename\*=(.+)") {
$filename = Decode-RFC2231 $matches[1].Trim()
}
elseif ($h -match 'filename="([^"]+)"') {
$filename = $matches[1]
}
# Base64デコード
if ($h -match "base64") {
$bytes = Decode-Base64 $b
$outPath = Join-Path $OutDir $filename
[System.IO.File]::WriteAllBytes($outPath, $bytes)
}
}
}
}