[小ネタ] 日本語版Windows EC2のユーザーデータに日本語コメントを書いたら、スクリプトが1行も実行されなかった

[小ネタ] 日本語版Windows EC2のユーザーデータに日本語コメントを書いたら、スクリプトが1行も実行されなかった

日本語版Windows EC2のユーザーデータで、PowerShellスクリプトに日本語コメントを書くと、スクリプトが1行も実行されないことがあります。エラーの調べ方と、ユーザーデータで取れる対策をまとめました。
2026.09.30

こんにちは、林です。

とある案件で、Windows Server 2025のEC2をユーザーデータで初期設定していました。
タイムゾーンやファイアウォールの設定を並べたPowerShellスクリプトです。

引き継ぎを考えてコメントを日本語で書いたところ、ユーザーデータが1行も実行されなくなりました。ログを見てもエラーの内容までは書かれておらず、最初は原因の見当がつきませんでした。

先に結論

日本語コメントの直後の行が、コメントに巻き込まれて構文エラーになっていました。

EC2Launch v2が書き出したスクリプトを、日本語版WindowsのPowerShellがCP932として読むため、行末で改行が消えることがあります。ユーザーデータには日本語のコメントを書かないのが確実です。

今回の環境

項目 内容
OS Windows Server 2025日本語版
EC2Launch v2.5.2
Windows PowerShell 5.1.26100
システムロケール 日本語(CP932)
ユーザーデータの指定 CloudFormationのUserData
スクリプトの改行コード LF

エラーの調べ方

次のユーザーデータでEC2を起動しました。日本語のコメント2行の直後にtry {があります。

<powershell>
Start-Transcript -Path C:\Windows\Temp\userdata.log -Append
# ICMP(ping)の受信許可
# 受信規則は既定で無効なので有効化する
try {
    Enable-NetFirewallRule -Name "FPS-ICMP4-ERQ-In" -ErrorAction Stop
} catch {
    Write-Output "failed: $_"
}
Stop-Transcript
</powershell>

起動しても、Start-Transcriptで作られるはずのC:\Windows\Temp\userdata.logがありません。

EC2Launch v2のログC:\ProgramData\Amazon\EC2Launch\log\agent.logを見ると、スクリプトがエラーを出力したことが分かります。

Info: Script file is created at: C:\Windows\system32\config\systemprofile\AppData\Local\Temp\EC2Launch2485221373\UserScript.ps1
Info: Error file is created at: C:\Windows\system32\config\systemprofile\AppData\Local\Temp\EC2Launch2485221373\err.tmp
Error: Script produced error output.
Info: Stage: postReadyUserData completed.

エラーの中身はerr.tmpに書き出されていたので、確認してみました。

発生場所 C:\Windows\system32\config\systemprofile\AppData\Local\Temp\EC2Launch2485221373\UserScript.ps1:5 文字:1
+ } catch {
+ ~
式またはステートメントのトークン '}' を使用できません。
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : UnexpectedToken

try {は書いてあるのに、} catch {が「対応するtryがない」と判定されています。構文エラーなので、スクリプトは1行も実行されなかったようです。

対策

ユーザーデータで取れる対策は4つです。

日本語をコメントに書かない

英数字だけのコメントなら起きません。

改行コードをCRLFにする

行末にCRが入るため、改行が消えなくなります。ユーザーデータに書いた改行コードは、EC2Launch v2が書き出すファイルにもそのまま残ります。

テンプレートをLFで保存しているとLFのまま渡ります。エディタで改行コードをCRLFにして保存するか、Terraformで外部ファイルを読み込んでいる場合は渡すときに置き換えます。

user_data = replace(file("${path.module}/userdata.ps1"), "\n", "\r\n")

コメントは文字化けして表示されますが、PowerShellはコメント行を実行しないため、スクリプトの動作には影響しません。

スクリプトの先頭にBOMを入れる

EC2Launch v2が書き出すファイルにBOMが残るので、PowerShellがUTF-8として読みます。書き出されるのはタグの中身だけなので、BOMは<powershell>タグの直後に入れます。ただし、テンプレートに目に見えない文字を埋め込むことになります。

日本語コメントと実行行の間にASCIIだけの行を置く

# ----のような行を挟むと、消える改行がその行のものになるため、実行行は残ります。ただし、その行を消すと再発します。

私は最初この方法で直したのですが、あとからコメントを整理したときに罫線ごと消してしまい、また動かなくなりました。

原因

EC2Launch v2が書き出すスクリプトには、UTF-8の目印であるBOMが付いていません。Windows PowerShell 5.1はBOMがないファイルをCP932として読むので、UTF-8で書いたスクリプトがCP932として読まれます。

CP932の日本語は1文字2バイト、UTF-8の日本語は1文字3バイトです。
2バイトずつ読んでいくと切れ目がずれ、行末で1バイト余ることがあります。この1バイトが次の改行(0x0A)とセットで1文字として読まれ、改行が消えます。

今回は2つ目のコメント行がそうでした。
行末の「る」(E3 82 8B)の8Bが余り、改行を巻き込んでいます。

00000080   81 AE E3 81 A7 E6 9C 89 E5 8A B9 E5 8C 96 E3 81  ®ã§æå¹åã
00000090   99 E3 82 8B 0A 74 72 79 20 7B 0A 20 20 20 20 45  ã.try {.    E

CP932として読むと、try {がコメント行の続きになります。9行あったスクリプトが8行になりました。

Get-Content C:\...\UserScript.ps1 -Encoding Default
Start-Transcript -Path C:\Windows\Temp\userdata.log -Append
# ICMP・・ing・峨・蜿嶺ソ。險ア蜿ッ
# 蜿嶺ソ。隕丞援縺ッ譌「螳壹〒辟。蜉ケ縺ェ縺ョ縺ァ譛牙柑蛹悶☆繧・try {
    Enable-NetFirewallRule -Name "FPS-ICMP4-ERQ-In" -ErrorAction Stop
} catch {
    Write-Output "failed: $_"
}
Stop-Transcript

どの行で起きるかは行末のバイト次第なので、コメントを書き換えると結果が変わります。動いていたスクリプトが、コメントを直しただけで動かなくなることもあります。

まとめ

日本語版Windows EC2のユーザーデータでは、日本語コメントの直後の行がコメントに巻き込まれて、スクリプト全体が動かなくなることがあります。BOMなしのUTF-8がCP932として読まれるのが原因で、コメントに日本語を書かないか、改行コードをCRLFにすれば避けられます。

ユーザーデータが動かなくても、エラーはどこにも表示されません。私も最初はスクリプトの中身ばかり見ていて、err.tmpに気づくのに時間がかかりました。同じ症状のときは、agent.logに書かれたパスをまず開いてみてください。

この記事がどなたかの参考になれば幸いです。最後までご覧いただきありがとうございました!

参考

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2launch-v2.html

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-5.1

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事