PMPの流儀

我が家の流儀

我が家で気になったことを夫婦で取り上げていきます

MENU

PowerShell バックアップと過去データの削除

データのバックアップと、古いバックアップを削除するバッチ処理を紹介します。バックアップには定番のrobocopyを使用します。古いディレクトリの削除をどう実現するかがポイントです。
バッチファイルとPowerShellの両方の形式で記載して、両者の違いを比較してみます。

仕様

シンプルに以下の仕様にします。
ディレクトリを日付ごとのフォルダを作成してミラーリングを作成します。
・7日前以上のディレクトリは削除します。

バッチファイル

昔ながらのバッチファイルでは、forfilesの行がなんとも複雑です。呪文です。D -7が7日前を指定しています。

@echo off

set src_dir=c:\temp\backuptest\src
set dst_home=c:\temp\backuptest\dst
set dst_dir=%dst_home%\%DATE:/=%

mkdir %dst_dir%
robocopy %src_dir% %dst_dir% /MIR /R:0 /W:0

forfiles /P %dst_home%  /C "cmd /c if @isdir==TRUE rmdir @path /S /Q" /D -7

PowerShell

PowerShellの真骨頂は最終行です。オブジェクトにフィルターをかけて、最終段で個々のオブジェクトの処理(ディレクトリ削除)をしています。
エレガントです
AddDays(-7) が7日前を指定しています。

$now = Get-Date

$src_dir = "C:\temp\backuptest\src"
$dst_home = "C:\temp\backuptest\dst"
$dst_dir = Join-Path $dst_home $now.ToString("yyyyMMdd")

New-Item $dst_dir
robocopy $src_dir $dst_dir /MIR /R:0 /W:0

Get-ChildItem $dst_home | ? {$_.PSIsContainer} | ? {$_.LastWriteTime -le $now.AddDays(-7)} | % {Remove-Item $_ -Force -Recurse}

最終行を少し解説します。
パイプは知っている人が多いと思います。あるコマンドの結果を、別のコマンドの入力にするときに使われます。

日本語で書くとこんな感じです。削除対象のディレクトリ探し出し、最後に削除しています。
$dst_homeディレクトリ以下のディレクト・ファイルを取得 | ディレクトリのみ | 最終書き込み時間が7日以前 | 抽出されたディレクトリを削除

通常だと、foreachなどでループ展開して1つずつ処理していくところを1行に集約しています。
PowerShell では複雑な処理を簡潔な文で記載が可能となります。

具体的な考え方については別の記事で紹介します。