<#
簡易MIMEメール作成スクリプト
cURLで送信する際に利用する。
検証環境やクローズド環境で使用して下さい。
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]$From,
[string[]]$To,
[string]$Subject,
[string]$Body,
[string[]]$Attachments = @(),
[string]$OutFile = "mail.eml"
)
# ===== 基本 =====
$CRLF = "`r`n"
# ===== RFC2047 Subject =====
function Encode-Subject( $string ) {
$bytes = [System.Text.Encoding]::UTF8.GetBytes( $string )
$b64data = [Convert]::ToBase64String( $bytes )
return "=?UTF-8?B?${b64data}?="
}
# ===== Base64(76文字折返し)=====
function To-Base64Lines( $bytes ) {
$b64data = [Convert]::ToBase64String( $bytes )
return ( ${b64data} -split "(.{1,76})" | Where-Object { $_ }) -join $CRLF
}
# ===== RFC2231 filename* =====
function Encode-RFC2231( $string ) {
$bytes = [System.Text.Encoding]::UTF8.GetBytes( $string )
$enc = ""
foreach ( $byte in $bytes ) {
if (
( $byte -ge 0x30 -and $byte -le 0x39 ) -or
( $byte -ge 0x41 -and $byte -le 0x5A ) -or
( $byte -ge 0x61 -and $byte -le 0x7A ) -or
$byte -in 0x2D, 0x2E, 0x5F, 0x7E
) {
$enc += [char]$byte
}
else {
$enc += "%" + $byte.ToString( "X2" )
}
}
return "UTF-8''$enc"
}
# ===== Date / Message-ID =====
$now = Get-Date
$dateStr = $now.ToString("ddd, dd MMM yyyy HH:mm:ss K", [System.Globalization.CultureInfo]::InvariantCulture)
$domain = ($From -split "@")[-1]
$msgid = "<" + [guid]::NewGuid().ToString() + "@$domain>"
# ===== boundary =====
$boundary = "----=_Boundary_" + [guid]::NewGuid().ToString("N")
# ===== ヘッダ =====
$headers = @()
$headers += "Date: $dateStr"
$headers += "Message-ID: $msgid"
$headers += "From: $From"
$headers += "To: " + ($To -join ", ")
$headers += "Subject: " + ( Encode-Subject $Subject )
$headers += "MIME-Version: 1.0"
if ($Attachments.Count -gt 0) {
$headers += "Content-Type: multipart/mixed; boundary=""$boundary"""
}
else {
$headers += "Content-Type: text/plain; charset=UTF-8"
$headers += "Content-Transfer-Encoding: 8bit"
}
# ===== 本文 =====
$bodyLines = @()
if ( $Attachments.Count -gt 0 ) {
# 本文パート
$bodyLines += "--$boundary"
$bodyLines += "Content-Type: text/plain; charset=UTF-8"
$bodyLines += "Content-Transfer-Encoding: 8bit"
$bodyLines += ""
$bodyLines += $Body
# 添付
foreach ( $file in $Attachments ) {
$bytes = [System.IO.File]::ReadAllBytes( $file )
$name = [System.IO.Path]::GetFileName( $file )
# ASCIIフォールバック
$nameAscii = $name -replace '[^\x20-\x7E]', '_'
# RFC2231
$name2231 = Encode-RFC2231 $name
$bodyLines += ""
$bodyLines += "--$boundary"
$bodyLines += "Content-Type: application/octet-stream; name=""$nameAscii"""
$bodyLines += "Content-Transfer-Encoding: base64"
$bodyLines += "Content-Disposition: attachment; filename=""$nameAscii""; filename*=$name2231"
$bodyLines += ""
$bodyLines += (To-Base64Lines $bytes)
}
# 終端
$bodyLines += ""
$bodyLines += "--$boundary--"
}
else {
$bodyLines += $Body
}
# ===== 結合 =====
$all = ( $headers -join $CRLF ) + $CRLF + $CRLF + ( $bodyLines -join $CRLF )
# ===== 出力(CRLF維持)=====
[System.IO.File]::WriteAllText( $OutFile , $all , [System.Text.Encoding]::ASCII)