(powershell)xcopyコマンドでバックアップ世代管理
[powershell] xcopyコマンドでバックアップ
powershellからXCOPYコマンドを実行して、バックアップ世代管理を行うためのスクリプトを作成してみました。
Github版はコチラです。
https://github.com/persimoon/powershell-xcopy
当スクリプトの目的
- このスクリプトは、Windows環境でバックアップ世代管理を行うことができるPowershellスクリプトです。
- 重要なデータが含まれるフォルダを、ネットワーク接続された別コンピューターやNas等のデバイスにバックアップする際に使用することができます。もちろん、同じPCにUSB接続されたポータブルハードディスクでも構いません。
バックアップ対象のデータサイズが大きい場合の注意点
- バックアップ方法は、対象フォルダ全体のレプリケーションですが、世代管理によりフォルダ分けされます。
- そのためバックアップ世代数分のデータ容量が必要となります。バックアップ対象のデータ量が多く、また保持しておくたいバックアップ世代数が多いほど、多くのディスク容量を消費することになることに注意が必要です。
- さらに、バックアップ対象のデータ量が多くなるにつれて、xcopyコマンド実行にかかる時間と、古くなったバックアップ世代のデータを削除するためにかかる時間が長くなりますので、所要時間についても考慮が必要となります。
概要
- バックアップ処理は、xcopyコマンドを呼び出して実行しています。xcopyコマンドは、コピー手段としては信頼性が高いとされています。
バックアップ世代管理は、powershellが備えるコマンドにより実行しています。
どのようにバックアップが行われるか、下記の"サンプルコードの環境例", "実行ログのサンプル"を参照してください。
- 実行環境に合わせたパラメータ設定方法を行ってください。
- 当スクリプトはVisual Studio Code上で作成しました。実行環境に合わせたパラメータ設定を行うために、ps1ファイルを編集して保存する場合は、文字エンコーディングを「utf8 With BOM」としてください。エンコードが異なると、パス名に含まれる日本語が文字化けしたり、うまく動作しなかったりするようです。
当スクリプトに関係する外部サイト
- Docs Windows Server> Windows のコマンド> xcopy
https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/xcopy
実行環境に合わせたパラメータ設定方法
- ps1ファイル内の、以下の変数を実行環境に合わせて書き換えてください。
$FromPath = "バックアップ対象フォルダのパス名" $DestPath = "バックアップ先フォルダのパス名" ※末尾には\を付けてください $TranscriptPath = "実行ログの出力先パス名" ※ファイル名を含む完全パス名
[バックアップ対象フォルダ] $FromPath = "バックアップ対象フォルダのパス名" [バックアップ先フォルダ(世代フォルダの作成先)] $DestPath = "バックアップ先フォルダのパス名\" [例] $FromPath = "C:\Folder1" $DestPath = "C:\Folder1_backup\" 実行時、[$DestPath+日付時刻文字列]でバックアップ先フォルダが作成されます。 (例えば 2022年3月5日14時01分02秒に実行した場合) $DestPath ="C:\Folder1_backup\20220304_140102\" フォルダ内にバックアップが作成されます。 [実行ログの出力先パス名] $TranscriptPath = "フルパス" [例] # $TranscriptPath = "C:\Folder1\backup_xcopy_datetime.log"
サンプルコードの環境例
- サンプルコードは、以下のフォルダ階層を想定したものとなっています。
[バックアップ対象のフォルダ] C:\FOLDER1 [バックアップ世代フォルダ内に作成される世代フォルダ] C:\FOLDER1_BACKUP └[yyyyMMdd-HHmmss]フォルダ ※世代数分が保持されます。
- バックアップ世代数を5世代とした場合、以下の例のようにバックアップ先フォルダ内には、常に直近の5世代分(5フォルダ)が維持されます。
- 以下の状態から新たに当スクリプトを実行すると、新たに[yyyyMMdd-HHmmss]フォルダ(実行した日時分秒のフォルダ)が作成され、新たに保持すべき世代数としてカウンタとされます。そのため[20220306-101721]フォルダは6世代目となり保持対象を超え、フォルダごと削除されます。
[バックアップ世代フォルダ内に作成される世代フォルダ] C:\FOLDER1_BACKUP ├─20220306-101721 ├─20220306-101755 ├─20220306-101820 ├─20220306-101905 └─20220306-101931
実行ログのサンプル
- PowerShellのトランスクリプトにより、以下のようなログファイルが出力されます。
- 実環境において、ログファイルから読み取れる大切な内容は以下のとおりです。
********************** Windows PowerShell トランスクリプト開始 ********************** トランスクリプトが開始されました。出力ファイル: C:\backup_xcopy_datetime.log . FromPath = C:\Folder1 DestPath2 = C:\Folder1_backup\20220306-101308\ . ディレクトリ: C:\Folder1_backup Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2022/03/06 10:13 20220306-101308 . XCOPYコマンドを開始します . . XCOPYコマンドが終了しました . xcopy終了コード=0:ファイルはエラーなしでコピーされました。 . バックアップ世代管理の処理を開始 . バックアップ先ベースフォルダ名:C:\Folder1_backup\ バックアップのサブフォルダの総数:6 保持する世代数:5 削除されるフォルダ数:1 1 : 古いバックアップ世代のため削除 : 20220306-101004 2 : 保持対象:20220306-101006 3 : 保持対象:20220306-101146 4 : 保持対象:20220306-101220 5 : 保持対象:20220306-101242 6 : 保持対象:20220306-101308 . バックアップ世代管理の処理が終了しました . ********************** Windows PowerShell トランスクリプト終了 **********************
ソースコード
# -------------------------------------------------------------------------------------------------------------------- # $FromPath = "バックアップ対象フォルダのパス名" # $DestPath = "バックアップ先フォルダのパス名\" # [例] # $FromPath = "C:\Folder1" ※末尾には\を付けないでください。 # $DestPath = "C:\Folder1_backup" ※末尾に\を付けてください。 # # 実行時、[$DestPath+日付時刻文字列]でバックアップ先フォルダが作成されます。 # (例えば 2022年3月5日14時01分02秒に実行した場合) # $DestPath ="C:\Folder1_backup\20220304_140102\" フォルダ内にバックアップが作成されます。 # -------------------------------------------------------------------------------------------------------------------- # ▼ 実行環境に合わせて書き換えてください。 $FromPath = "C:\Folder1" $DestPath = "C:\Folder1_backup\" $BackupHistoryCount = 5 # -------------------------------------------------------------------------------------------------------------------- # $TranscriptPath = "D:\バックアップXCOPY\backup_xcopy_datetime.log" # ログファイルの出力先パス名を指定してください。 # -------------------------------------------------------------------------------------------------------------------- # ▼ 実行環境に合わせて書き換えてください。 $TranscriptPath = "C:\Folder1\Xcopy_with_HistoryManagement.log" # -------------------------------------------------------------------------------------------------------------------- # 以下は実行コードです。変更しないでください。 # -------------------------------------------------------------------------------------------------------------------- # PowerShellログ出力の開始 Start-Transcript $TranscriptPath # 日時分秒別のパスを作成 $ymdhms=Get-Date -Format "yyyyMMdd-HHmmss" $DestPath2 = $DestPath + $ymdhms + "\" ECHO . ECHO "FromPath = $FromPath" ECHO "DestPath2 = $DestPath2" ECHO . # バックアップ先フォルダを作成 New-Item ( $DestPath2 ) -ItemType Directory ECHO . ECHO "XCOPYコマンドを開始します" ECHO . XCOPY $FromPath $DestPath2 /S /Y /E /C /H # エラー検査 $XcopyExitCode=$LastExitCode ECHO . ECHO "XCOPYコマンドが終了しました" ECHO . if( ( $XcopyExitCode ) -eq 0 ) { ECHO xcopy終了コード=0:ファイルはエラーなしでコピーされました。 } if( ( $XcopyExitCode ) -eq 1 ) { ECHO xcopy終了コード=1:コピーするファイルが見つかりませんでした。 } if( ( $XcopyExitCode ) -eq 2 ) { ECHO xcopy終了コード=2:ユーザーが Ctrl + C キーを押して xcopy を終了しました。} if( ( $XcopyExitCode ) -eq 4 ) { ECHO xcopy終了コード=4:初期化エラーが発生しました。 メモリまたはディスク領域が不足しているか、コマンド ラインに無効なドライブ名または無効な構文が入力されました。} if( ( $XcopyExitCode ) -eq 5 ) { ECHO xcopy終了コード=5:ディスク書き込みエラーが発生しました。 } ECHO . ECHO "バックアップ世代管理の処理を開始" ECHO . # バックアップ世代管理 [System.IO.DirectoryInfo[]] $DestPath_SubFolders = dir $DestPath -Directory $DestPath_SubFolders_Count = $DestPath_SubFolders.Count $DestPath_SubFolders_EraseCount = $DestPath_SubFolders.Count - $BackupHistoryCount echo "バックアップ先ベースフォルダ名:$DestPath" echo " バックアップのサブフォルダの総数:$DestPath_SubFolders_Count" echo " 保持する世代数:$BackupHistoryCount" echo " 削除されるフォルダ数:$DestPath_SubFolders_EraseCount" $cnt = 0 foreach ($item in $DestPath_SubFolders) { $cnt = $cnt + 1 if( ( $cnt -le $DestPath_SubFolders_EraseCount ) -eq "true" ){ ECHO "$cnt : 古いバックアップ世代のため削除 : $item" $eraseFullPath = $DestPath + $item Remove-Item -Path $eraseFullPath -Recurse -Force } else { ECHO "$cnt : 保持対象:$item" } } ECHO . ECHO "バックアップ世代管理の処理が終了しました" ECHO . # PowerShellログ出力の終了 Stop-Transcript