データのバックアップと、古いバックアップを削除するバッチ処理を紹介します。バックアップには定番の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 では複雑な処理を簡潔な文で記載が可能となります。
具体的な考え方については別の記事で紹介します。