PowerShellでログローテーションを自動化!

Windowsサーバーやシステムの運用管理において、避けて通れないのが「増え続けるログファイル」への対応です。
「いつの間にかログが溜まってディスク容量を圧迫している」
「過去の古いログを、手作業で一つずつ圧縮したり削除したりするのが面倒」
このような悩みを抱えているシステム管理者は少なくありません。
ログを長期間放置すると、最悪ケースではOSの動作が不安定になり、サービス停止などの深刻なシステムトラブルを招く恐れがあります。
そこで本記事では、PowerShellを使ってログ管理の作業をすべて自動化する「ログローテーションスクリプト」を紹介します。
この記事を読めば、設定した保存期間(例:30日、90日)を超えたログファイルを、全自動でZIP圧縮・完全削除する仕組みが手に入ります。
システムに不慣れな方でも、コピペするだけで安全に導入できるよう設計しています。
もう容量不足の警告に怯える必要はありません。
スクリプトをサクッと設定し、毎日のログ管理作業から解放されましょう!
この記事を読んでほしい人
- サーバーやシステムのログが溜まり、ディスク容量を圧迫して困っている人
- PowerShellを使ってWindows環境のログ管理(圧縮・削除)を自動化したい人
- コピペでそのまま使える安全なログローテーションスクリプトを探している人
目次
なぜ必要?PowerShellでログローテーションを行うべき理由
Windowsサーバーや各種システムを運用する上で、ログファイルの適切な管理は極めて重要です。システムが稼働している限り、アクセスログやエラーログといったデータは毎日休むことなく蓄積され続けます。
もしこれらのログを長期間にわたって放置してしまうと、ディスク容量を少しずつ圧迫していくことになります。
最終的にはハードディスクの空き容量がゼロになり、OSや重要なアプリケーションが突然停止してしまうといった深刻なシステムトラブルを引き起こすリスクがあるのです。
こうした容量不足によるシステムダウンを防ぎ、サーバーを健全な状態で維持するために必須となる仕組みが「ログローテーション」です。
ログローテーションとは、古くなったログファイルを一定の基準でアーカイブ(圧縮)したり、完全に削除したりして、常にディスクの空き容量を一定以上に保つ運用のことを指します。
Windows環境において、このログローテーションを最も効率的かつ柔軟に実現できる手段が「PowerShell」の活用です。
PowerShellを使えば、標準機能であるコマンド(Cmdlet)を組み合わせるだけで、特定のフォルダ内にあるファイルの「最終更新日」を自動的に判別できます。
たとえば「30日以上前のものはZIP形式で圧縮し、90日以上前のものは完全に削除する」といった、企業の保存ポリシーに合わせた細かなスケジュール管理をプログラムで正確に実行できるようになります。
外部の専用管理ソフトや有料のツールを導入する必要がなく、Windowsの標準環境だけで今すぐ安全に自動化の仕組みを構築できる点が、PowerShellでログローテーションを行う最大のメリットです。
コピペで使える!PowerShellログローテーションスクリプト
Windows環境で今すぐ導入できる、汎用的なログローテーションスクリプトを作成しました。
メモ帳などのテキストエディタにコピー&ペーストし、拡張子を「.ps1」として保存するだけでそのまま利用可能です。
このスクリプトは、指定されたフォルダ内のファイルをチェックし、「30日以上前のログファイルをZIP圧縮」した上で、「90日以上前の古いZIPファイルを自動削除」する処理を一括で行います。
# ==========================================
# PowerShell ログローテーションスクリプト
# ==========================================
# ---- [基本設定] 独自の環境に合わせて変更してください ----
$TargetDir = "C:\inetpub\logs\LogFiles" # 対象のログフォルダ
$ArchiveAge = 30 # 圧縮対象とする日数(これより古いファイルを圧縮)
$DeleteAge = 90 # 削除対象とする日数(これより古いZIPファイルを削除)
$ZipPrefix = "Archive_" # 圧縮後のファイル名に付与するプレフィックス
# 現在の日時を取得
$Now = Get-Date
# ---- [処理1] 古いZIPファイルの削除処理 ----
Write-Host "【処理開始】古いアーカイブ(ZIP)の削除を確認中..."
if (Test-Path $TargetDir) {
# 削除基準日を計算
$DeleteLimitDate = $Now.AddDays(-$DeleteAge)
# 対象となる古いZIPファイルを取得して削除
Get-ChildItem -Path $TargetDir -Filter "*.zip" -File | Where-Object {
$_.LastWriteTime -lt $DeleteLimitDate
} | ForEach-Object {
Write-Host "削除中: $($_.FullName) (最終更新日: $($_.LastWriteTime))"
Remove-Item -Path $_.FullName -Force
}
}
# ---- [処理2] ログファイルのZIP圧縮処理 ----
Write-Host "【処理継続】対象ログファイルの圧縮処理を実行中..."
if (Test-Path $TargetDir) {
# 圧縮基準日を計算
$ArchiveLimitDate = $Now.AddDays(-$ArchiveAge)
# 対象となる古いログファイル(.log)を取得
$LogFiles = Get-ChildItem -Path $TargetDir -Filter "*.log" -File | Where-Object {
$_.LastWriteTime -lt $ArchiveLimitDate
}
# 対象ファイルがある場合のみ圧縮を実行
if ($LogFiles) {
$DateStr = $Now.ToString("yyyyMMdd_HHmmss")
$ZipFileName = "${ZipPrefix}${DateStr}.zip"
$ZipPath = Join-Path -Path $TargetDir -ChildPath $ZipFileName
Write-Host "以下のファイルを ${ZipFileName} に圧縮します:"
# 1つのZIPファイルにまとめて圧縮
Compress-Archive -Path $LogFiles.FullName -DestinationPath $ZipPath -Force
# 圧縮が成功したら、元となったログファイルを削除
if (Test-Path $ZipPath) {
Write-Host "圧縮成功。元のログファイルを削除します..."
$LogFiles | ForEach-Object {
Remove-Item -Path $_.FullName -Force
}
}
} else {
Write-Host "圧縮対象の古いログファイルは見つかりませんでした。"
}
}
Write-Host "【処理完了】すべてのログローテーション作業が終了しました。"スクリプトの基本設定と仕組み
このスクリプトは、Windowsの標準機能であるPowerShell 5.1以上であれば、追加のライブラリをインストールすることなく動作します。
安全かつ効率的に運用できるよう、内部では主に以下の2つの仕組み(コマンドレット)を軸に処理を組み立てています。
まず1つ目は、ファイルの抽出を行う「Get-ChildItem」と、日付によるフィルタリングの仕組みです。
「LastWriteTime(最終更新日)」プロパティを参照し、現在の日時から逆算した基準日($ArchiveLimitDate や $DeleteLimitDate)よりも古いファイルだけを正確に特定します。
これにより、現在システムが書き込みを行っている最新のログファイルを誤って操作するリスクを排除しています。
2つ目は、標準の圧縮コマンドである「Compress-Archive」の活用です。抽出された古いログファイル群を一括で指定し、タイムスタンプを冠した1つのZIPファイル(例:Archive_20260531_000000.zip)へ強力に圧縮します。
そして、最も重要な安全対策として、「ZIPファイルの作成(圧縮)が完全に成功したことを Test-Path で確認できた場合のみ、元のログファイルを Remove-Item で削除する」というパイプライン処理を採用しています。
万が一、圧縮処理の途中でエラーが発生したとしても、大切な過去のログデータが消失しないよう、2段構えの安全設計を施しているのがこのスクリプトの特徴です。
安全に運用するために!スクリプトを使用する際の注意点
紹介したログローテーションスクリプトは非常に強力ですが、本番環境のサーバーへ導入する前には、トラブルを防ぐためにいくつか確認しておくべき重要な注意点があります。
最も気をつけなければならないのが、「ログファイルが他のアプリケーションによってロック(占有)されていないか」という点です。
WindowsのサービスやWebサーバー(IISなど)の中には、稼働中にログファイルを開きっぱなしにして、常に書き込み可能な状態(ロック状態)を維持するシステムが多く存在します。
ファイルがロックされていると、PowerShellがファイルをZIP圧縮したり削除したりしようとした際に「プロセスがファイルにアクセスできません」というエラーが発生し、スクリプトの処理が途中で失敗してしまいます。
この問題を回避するための具体的な対策は以下の通りです。
- アプリケーションの動作仕様を確認する:
日付が変わると自動的に新しいログファイルを作成し、古いファイルのロックを解除する仕様になっているか確認します(例:IISの標準ログなど)。 - ローテーションの実行タイミングをずらす:
アクセスや書き込みが最も少ない深夜や早朝の時間帯(午前2時〜4時など)を狙ってスクリプトを実行するように計画します。 - 一時的にサービスを停止する(必要な場合のみ):
どうしても稼働中にロックが解除されないログの場合は、スクリプトの先頭と末尾にサービスの一時停止・再開コマンド(Stop-Service/Start-Service)を組み込むことを検討してください。
また、環境特有の注意点として、寒冷地である北海道などに設置されたデータセンターや、現地の自社オフィス内に社内サーバー(オンプレミス環境)を置いている場合、冬季の運用には隠れた盲点があります。
万が一、大雪などの悪天候による停電やネットワーク障害が発生すると、夜間の自動処理が予期せぬタイミングで中断されるリスクがゼロではありません。
スクリプトを過信せず、初回は必ず少量のテスト用ログファイルを用意した「テスト環境」で動作確認を行い、意図した通りに圧縮・削除が実行されるかを見極めてから本番サーバーへ適用してください。
スクリプトが正常に動かない場合のチェックポイント
スクリプトを実行した際、意図した通りにファイルの圧縮や削除が行われない場合は、以下の4つのポイントを上から順番に確認してください。
原因の多くはPowerShellの記述ミスではなく、Windows側の環境設定や権限にあります。
- 1. 実行ポリシー(Execution Policy)が制限されていないか
Windowsの初期設定では、セキュリティ対策としてPowerShellスクリプト(.ps1)の実行が禁止されています。
スクリプトを実行した際に赤文字でエラーが出る場合は、管理者権限でPowerShellを開き、以下のコマンドを実行してスクリプトの実行を許可してください。
PowerShellSet-ExecutionPolicy RemoteSigned -Force - 2. スクリプトを「管理者権限」で実行しているか
ログファイルが保存されているフォルダ(例:C:\inetpub\logsやC:\Program Files配下など)は、Windowsのシステムによって厳重に保護されています。
一般ユーザーの権限でスクリプトを動かそうとすると、ファイルの読み込みや削除の段階で「アクセスが拒否されました」という権限エラー(UnauthorizedAccessException)になります。
手動でテストする際は、必ず「管理者として実行」したPowerShellプロンプトを使用してください。 - 3. フォルダのパス指定の末尾に「
\」が入っていないか
基本設定の$TargetDirで指定するフォルダのパスの末尾に「\」を付けてしまうと(例:"C:\logs\")、後続のパス結合処理などでエラーが発生したり、ファイルが正しく検出されなくなったりする原因になります。
パスを指定する際は、末尾にスラッシュやバックスラッシュを含めない形式(例:"C:\logs")で統一してください。 - 4. 圧縮対象となるファイルの「最終更新日」が本当に基準を満たしているか
「スクリプトはエラーなく終了するのに、なぜかファイルが圧縮されない」という場合、対象ファイルのタイムスタンプが条件を満たしていないケースがほとんどです。
Windowsのファイルシステムにおいて、ファイルの内容が1文字でも更新されると「最終更新日(LastWriteTime)」は本日の日付に書き換わります。
テストを行う際は、エクスプローラー上でファイルのプロパティを開き、タイムスタンプが設定した日数(例:30日前)よりも確実に古いものであるかを確認してください。
タスクスケジューラを組み合わせて完全自動化する方法
PowerShellスクリプトが完成したら、Windowsの標準機能である「タスクスケジューラ」に登録しましょう。
これにより、毎日決まった時間にスクリプトがバックグラウンドで自動実行され、人間の手を一切煩わせることのない「完全自動化」のログローテーション環境が整います。
設定の手順は以下の通りです。
- 手順1:タスクスケジューラを起動する
スタートメニューの検索バーに「タスクスケジューラ」と入力して起動します。
右側の「操作」メニューから「基本タスクの作成」をクリックし、任意の名前(例:「ログローテーション自動実行」など)を入力して「次へ」進みます。 - 手順2:トリガー(実行スケジュール)を設定する
タスクを実行するタイミングを選択します。
ログローテーションは毎日実行するのが一般的であるため、「毎日」を選択し、システムの負荷が最も低い深夜の時間帯(例:午前3時00分)を実行時刻に指定してください。 - 手順3:操作で「プログラムの開始」を選択する
「どのような操作を実行しますか?」という画面が表示されたら、「プログラムの開始」を選択して「次へ」進みます。 - 手順4:PowerShellを起動するための引数を指定する
ここが最も重要な設定ポイントです。「プログラム/スクリプト」の欄と、「引数の追加(オプション)」の欄にそれぞれ以下の通り正確に入力してください。- プログラム/スクリプト:
powershell.exe - 引数の追加(オプション):
-ExecutionPolicy Bypass -File "C:\Scripts\LogRotation.ps1"※"C:\Scripts\LogRotation.ps1"の部分は、作成したスクリプトを実際に保存したフルパスに書き換えてください。
- プログラム/スクリプト:
引数に -ExecutionPolicy Bypass を含めておくことで、Windows側のスクリプト実行ポリシーに関わらず、このタスクが実行される時だけ一時的に制限を回避して確実にスクリプトを動かすことができます。
最後に「完了」をクリックすれば登録は終了です。
作成されたタスクのプロパティを開き、「ユーザーがログオンしているかどうかに関わらず実行する」および「最上位の特権で実行する」にチェックを入れておくことで、サーバーに誰もサインインしていない状態でも、管理者権限で確実にスクリプトが自動実行されるようになります。
まとめ
増え続けるシステムログを放置することは、ディスク容量の圧迫や予期せぬシステムダウンを招く大きなリスクとなります。
今回ご紹介したPowerShellスクリプトを活用すれば、以下の手順でログ管理の課題をすっきりと解決できます。
- 保存ポリシーに合わせた自動化:
30日以上前のログファイルを自動でZIP圧縮し、90日以上前の古いファイルを自動で削除 - 安全第一の設計:
圧縮が完全に成功したことを確認してから元ファイルを削除するため、データ消失のリスクを最小限に抑制 - 完全自動化の実現:
Windows標準の「タスクスケジューラ」と組み合わせることで、深夜などの時間帯にバックグラウンドで定期実行
手作業によるログ管理は手間がかかるだけでなく、消してはいけない最新のログを誤って削除してしまうといったヒューマンエラーの原因にもなりかねません。
Windowsの標準機能だけで今すぐ構築できるこのクリーンな自動化の仕組みを取り入れて、安全かつスマートなサーバー運用を実現しましょう!
