【PowerShell】古いファイルを削除・移動する方法|更新日(LastWriteTime)で絞り込む

【PowerShell】古いファイルを削除・移動する方法|更新日(LastWriteTime)で絞り込む PowerShell

ログやバックアップ、ダウンロードファイルなどは、放っておくとどんどん溜まっていきます。「30日より前の古いファイルだけ削除したい」「古いログを別フォルダに退避したい」——こうした整理は、PowerShellなら更新日(LastWriteTime)で絞り込むだけで自動化できます。タスクスケジューラと組み合わせれば、定期的な自動クリーンアップも作れます。

つまずきやすいのは、「○日より古い」を表す比較が-lt(小なり)になることです。更新日が基準日より「小さい(前)」=古い、という関係を直感と逆に感じる人が多いポイントです。また、削除は取り消せないため-WhatIfでの事前確認が欠かせません。この記事では、実機のPowerShell 5.1で確認しながら、古いファイルの整理を整理します。

先に結論

  • 更新日はLastWriteTime、N日前の基準は(Get-Date).AddDays(-30)で作ります。
  • 絞り込みはWhere-Object { $_.LastWriteTime -lt $cutoff }です。
  • 「基準より古い」は-lt(更新日が基準日より小さい=前)。「新しい」は-gt
  • 削除はRemove-Item必ず-WhatIfで確認してから本実行します。
  • 退避するならMove-Itemで別フォルダへ移します。
  • 作成日で絞りたいときはCreationTimeを使います。

基準日を作る(Get-Date).AddDays(-30)Get-Dateで日付をフォーマットする、絞り込みのWhere-ObjectWhere-Object・Select-Object、対象の取得はファイル・フォルダ操作もあわせて参考になります。重複ファイルの検出と組み合わせれば、フォルダ整理がさらに進みます。

スポンサーリンク

考え方:更新日で絞り込む

古いファイルの整理は、3つのステップで考えます。「①基準となる日付を作る → ②その日より前に更新されたファイルを絞り込む → ③削除または移動する」という流れです。基準日は(Get-Date).AddDays(-30)のように、今日からさかのぼって作ります。

ファイルの日時を確認する LastWriteTime

ファイルには、最後に内容が変更された日時LastWriteTimeと、作成された日時CreationTimeが記録されています。まずはこれを確認してみます。

ファイルの日時を見る
# 更新日(LastWriteTime)と作成日(CreationTime)を表示
Get-ChildItem "C:\logs" -File |
    Select-Object Name, LastWriteTime, CreationTime

# 更新日が新しい順に並べる
Get-ChildItem "C:\logs" -File | Sort-Object LastWriteTime -Descending

実機でも、各ファイルにLastWriteTime(更新日時)とCreationTime(作成日時)の両方が記録されていることを確認しました。古いファイルの整理では、通常は「最後にいつ使われたか」を表すLastWriteTimeを基準にします。

N日より古いファイルを抽出する

「30日より古いファイル」を抽出するには、基準日(Get-Date).AddDays(-30)を作り、Where-ObjectLastWriteTimeがそれより前のものを絞り込みます。

30日より古いファイルを抽出
# 30日前の日付を基準にする
$cutoff = (Get-Date).AddDays(-30)

# 更新日が基準より古い(前)のファイルを抽出
Get-ChildItem "C:\logs" -File |
    Where-Object { $_.LastWriteTime -lt $cutoff }

# サブフォルダも含めるなら -Recurse
Get-ChildItem "C:\logs" -Recurse -File |
    Where-Object { $_.LastWriteTime -lt $cutoff }

実機でも、更新日を5日前にしたファイル3つと100日前にしたファイル4つを用意し、(Get-Date).AddDays(-30)を基準に-ltで絞り込んだところ、100日前の4ファイルだけが「30日より古い」として正しく抽出されました。AddDays(-30)はマイナスを付けることで「30日前」を表します。AddHoursAddMonthsなどもあり、時間単位や月単位の基準も作れます。

「より古い」は -lt(更新日が小さい)

ここが最大の注意点です。「基準日より古い」を表す比較は-lt(less than=小なり)です。更新日が基準日より「小さい(過去)」ほど古い、という関係になるためです。逆に「基準日より新しい(最近)」は-gt(greater than)です。

-lt と -gt の使い分け
$cutoff = (Get-Date).AddDays(-30)

# 古い(30日より前に更新)= -lt … 削除・退避の対象になりやすい
Get-ChildItem "C:\logs" -File | Where-Object { $_.LastWriteTime -lt $cutoff }

# 新しい(30日以内に更新)= -gt … 最近使ったファイル
Get-ChildItem "C:\logs" -File | Where-Object { $_.LastWriteTime -gt $cutoff }
古い=-lt、新しい=-gt

日付の比較では、過去の日付ほど「小さい」値として扱われます。そのため「基準日より古い(前)」を表すには-ltを使います。実機でも、30日前を基準に-ltで4件(古い側)、-gtで3件(新しい側)と、期待どおりに分かれました。「古いファイルを消したいのに、なぜか新しいファイルが対象になった」というときは、-lt-gtが逆になっていないか確認してください。なお、ちょうど基準日と同時刻のファイルも含めたい場合は-le(以下)・-ge(以上)を使います。比較演算子の詳しい使い方は別記事も参考になります。

古いファイルを削除する(-WhatIf必須)

抽出した古いファイルを削除するにはRemove-Itemを使います。ただし削除は取り消せません。必ず最初に-WhatIfを付けて「何が消えるか」を確認し、問題なければ外して本実行します。

古いファイルの削除(まず -WhatIf)
$cutoff = (Get-Date).AddDays(-30)

# まず -WhatIf で消える対象だけを確認(実際には消さない)
Get-ChildItem "C:\logs" -File |
    Where-Object { $_.LastWriteTime -lt $cutoff } |
    Remove-Item -WhatIf

# 表示内容を確認してから、-WhatIf を外して本実行
# Get-ChildItem "C:\logs" -File |
#     Where-Object { $_.LastWriteTime -lt $cutoff } |
#     Remove-Item
削除の前に必ず -WhatIf で確認する

実機で確認したところ、Remove-Item -WhatIfを付けて実行すると「対象 … に対して操作 “ファイルの削除” を実行しています」と消える予定のファイルが表示されるだけで、実際には削除されませんでした(対象のold1.txtはそのまま残っていました)。古いファイルの一括削除は、絞り込み条件を1つ間違えると大事なファイルまで消してしまう危険があります。必ず-WhatIfで対象を目で確認し、意図したファイルだけが並んでいることを確かめてから本実行してください。心配なら、削除ではなく次の「移動」で別フォルダに退避するほうが安全です。

古いファイルを別フォルダへ移動する

すぐに削除するのが不安なときは、Move-Itemで古いファイルを退避用フォルダに移動しておく方法が安全です。しばらく置いて問題がなければ、フォルダごと削除します。

古いファイルを退避フォルダへ移動
$cutoff = (Get-Date).AddDays(-30)
$archive = "C:\logs\archive"

# 退避先フォルダを用意(無ければ作る)
if (-not (Test-Path $archive)) { New-Item -ItemType Directory -Path $archive | Out-Null }

# 30日より古いファイルを退避フォルダへ移動
Get-ChildItem "C:\logs" -File |
    Where-Object { $_.LastWriteTime -lt $cutoff } |
    Move-Item -Destination $archive

実機でも、30日より古い4ファイルをMove-Itemarchiveフォルダに移動でき、元のフォルダには新しい3ファイルだけが残りました。削除と違って移動なら、間違えても元に戻せます。退避先のフォルダはTest-Pathで存在を確認し、無ければNew-Itemで先に作っておくと安全です。

期間で絞る・作成日で絞る

「30日〜90日前」のように期間で絞ったり、更新日ではなく作成日(CreationTimeで絞ったりもできます。条件を-andでつなげば、範囲指定になります。

期間指定・作成日での絞り込み
# 30日〜90日前のファイル(範囲指定)
$from = (Get-Date).AddDays(-90)
$to   = (Get-Date).AddDays(-30)
Get-ChildItem "C:\logs" -File |
    Where-Object { $_.LastWriteTime -gt $from -and $_.LastWriteTime -lt $to }

# 作成日(CreationTime)が30日より古いもの
Get-ChildItem "C:\logs" -File |
    Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-30) }

更新日と作成日は別物です。LastWriteTimeは「最後に中身が変わった日時」、CreationTimeは「そのファイルが作られた日時」です。「ダウンロードしてから一定期間たったもの」を消したいならCreationTime、「ずっと使われていないもの」を消したいならLastWriteTime、と目的で使い分けます。範囲指定では、新しい側を-gt、古い側を-lt-andでつなぎます。

主な要素まとめ

古いファイル整理で使う要素をまとめます。

要素 働き
$_.LastWriteTime ファイルの更新日時
$_.CreationTime ファイルの作成日時
(Get-Date).AddDays(-30) 30日前の基準日を作る
-lt / -gt 古い(前)/ 新しい(後)
Where-Object { ... } 条件で絞り込む
Remove-Item -WhatIf 削除内容を確認(消さない)
Move-Item -Destination 別フォルダへ退避する

よくある失敗

「古い」を -gt にしてしまう

古い(基準より前)は-ltです。-gtだと新しいファイルが対象になります。

確認せずにいきなり削除する

必ずRemove-Item -WhatIfで対象を確認してから本実行します。不安なら移動で退避します。

AddDaysのマイナスを付け忘れる

「○日前」はAddDays(-30)とマイナスです。プラスだと未来の日付になります。

更新日と作成日を混同する

「使われていない」はLastWriteTime、「作られてから」はCreationTimeです。

-File を付けずフォルダも対象にする

Get-ChildItem -Fileでファイルだけに絞ります。フォルダを誤って消さないためです。

よくある質問

Q「30日より古いファイル」の条件式は?
A$cutoff = (Get-Date).AddDays(-30)で基準日を作り、Where-Object { $_.LastWriteTime -lt $cutoff }で絞り込みます。「古い(基準より前)」は更新日が小さい値になるため、比較は-lt(小なり)を使います。
Qなぜ「古い」が-ltなのですか?
A日付は過去ほど小さい値として扱われるためです。基準日より前(古い)の更新日は基準日より「小さい」ので-ltになります。逆に基準日より後(新しい)は-gtです。直感と逆に感じやすいので注意してください。
Q古いファイルを安全に削除するには?
AまずRemove-Item -WhatIfを付けて、消える予定のファイルを必ず目で確認してください。-WhatIfでは実際には削除されません。意図したファイルだけが並んでいることを確かめてから、-WhatIfを外して本実行します。不安ならMove-Itemで退避フォルダに移すほうが安全です。
Q更新日と作成日の違いは?
ALastWriteTimeは最後に中身が変更された日時、CreationTimeはファイルが作成された日時です。「長く使われていないファイル」を消すならLastWriteTime、「作られてから一定期間たったファイル」を消すならCreationTimeを基準にします。
Q定期的に自動で古いファイルを消すには?
A作成したスクリプトを.ps1ファイルとして保存し、Windowsのタスクスケジューラに登録すれば、毎日・毎週など定期的に自動実行できます。自動実行では確認ができないため、条件を十分テストし、削除ではなく移動にする、ログを残すなどの安全対策を入れておくと安心です。

まとめ

  • 基準日は(Get-Date).AddDays(-30)、絞り込みはWhere-Object { $_.LastWriteTime -lt $cutoff }
  • 「古い」は-lt、「新しい」は-gt。日付は過去ほど小さい値です。
  • 削除はRemove-Item必ず-WhatIfで確認してから本実行します。
  • 不安ならMove-Itemで退避フォルダへ。間違えても戻せます。
  • 作成日で絞るならCreationTime、期間指定は-andでつなぎます。

PowerShellなら、更新日を基準にした古いファイルの整理を簡単に自動化できます。「古いは-lt」「削除前に-WhatIf」の2点さえ押さえれば、ログやバックアップのクリーンアップを安全に行えます。タスクスケジューラと組み合わせて、フォルダが散らからない仕組みを作ってみてください。