(我が家のPC運用)自作バッチでバックアップ


我が家のPCバックアップ

我が家にはWindows10デスクトップPCがあり、運用の1タスクとして定期的にバックアップを実施しています。

  • システムのバックアップ:専用のアプリケーションで、アプリのスケジュール機能を使用して実施。
  • データのバックアップ:自作バッチで、タスクスケジューラに登録し実施。

バッチを自作した理由は

  • 実行の成否をテキストファイルに残したい。
  • バックアップした差分ファイルを知りたい。
  • 複数個所のデータバックアップを個別に実行したい、がそのパスを一元管理したい。
  • 作業の妨げにならないよう、裏でひっそりと実行したい。

今回はこの自作バッチについて説明します。

バッチの特徴

  • 以下の4ファイルで構成します。ファイルは全てSJISで、全て同一場所に配置します。(※過去にUTF8としていましたが、何かと不便のためSJISに変更しました)
    • backupExec.bat(これは任意のファイル名でOK)
    • setenv.bat
    • backupMain.bat
    • backupSub.bat
  • 実行するのはbackupExec.batです。このファイルは引数を指定してbackupMain.batを呼び出すのみです。
    バックアップのタスク数に応じて複数用意します。
    このファイルをタスクスケジューラに登録します。
  • backupMain.batは引数チェックやパスの存在チェックを実施した後、backupSub.batを呼び出します。
  • バックアップはbackupSub.bat内のrobocopyコマンドで実行します。
  • robocopyの結果をログファイルに出力します。
  • バックアップの元先やログファイルパスをsetenv.batにまとめます。

バッチのコード

backupExec.bat

  • 変数BASE_PATH:バッチファイルを格納しているパスを定義します。
  • 「call backupMain.bat 211」の「211」がsetenv.bat内のバックアップポリシーと紐付きます。
@echo off

set BASE_PATH=C:\pcmaintenance\batch
cd %BASE_PATH%
call backupMain.bat 211

exit %EXIT_CODE_NORMAL%

setenv.bat

  • 変数SYNC_LOG_PATH:バックアップログファイルを格納するパスを定義します。
  • 変数SYNC_FROM_PATH_211:バックアップ元のパスを定義します。
    backupExec.batのパラメートを「211」としたので、SYNC_FROM_PATH_211が採用されます。
  • 変数SYNC_TO_PATH_211:バックアップ先のパスを定義します。
  • 変数SYNC_OPTION_211:robocopyのオプションが必要な場合に定義します。
    下記のコードの場合、バックアップから除外するパスを指定しています。(ブラウザのキャッシュや、バックアップログファイル自身)
  • 変数は211の他にも複数定義し、backupExec.batか別のバッチファイルから実行可能です。
    下記のコードでは210というパラメータでもう一つのバックアップポリシーを定義し、backupExec.batとは別ファイル、別スケジュールで実施しています。
@echo off

set EXIT_CODE_NORMAL=0
set EXIT_CODE_ERROR=-1

set SYNC_LOG_PATH=D:\datas\log\backup
set SYNC_TO_BASE_PATH=E:\backup

rem ■低頻度バックアップ
set SYNC_FROM_PATH_211=D:
set SYNC_TO_PATH_211=%SYNC_TO_BASE_PATH%\低頻度バックアップ\システムデータ
set SYNC_OPTION_211=/xd "D:\datas\Chrome" /xd "D:\datas\log\backup"

rem ■高頻度バックアップ(ユーザ名はダミー)
set SYNC_FROM_PATH_210=C:\Users\user\デスクトップ
set SYNC_TO_PATH_210=%SYNC_TO_BASE_PATH%\高頻度バックアップ\デスクトップ

exit /b %EXIT_CODE_NORMAL%

backupMain.bat

  • バックアップ処理のメインです。
    引数チェック、パスの存在チェックを実施した後、backupSub.batを呼び出します。
@echo off

rem ****************
rem バックアップ実行バッチ
rem 第1引数:バックアップ対象パスのINDEX(setenv.bat内に記述)
rem ****************

set MYSHELL_NAME=%0
echo [START]%MYSHELL_NAME%
echo [INFO]%date% %time%
echo [INFO]ユーザ名:%USERNAME%


rem ****************
rem 共通初期設定
rem ****************

cd /d %~dp0
call .\setenv.bat > nul 2>&1
if not %errorlevel% == 0 (
    echo [ERROR]setenvバッチ実行エラー
    echo [END]%MYSHELL_NAME%
    exit /b %EXIT_CODE_ERROR%
)


rem ****************
rem 同期パスの取得
rem ****************

rem パスの取得
set PATH_INDEX=%1
setlocal enabledelayedexpansion
    rem 引数のINDEXでパス変数名を形成
    set SYNC_FROM_PATH_NAME=SYNC_FROM_PATH_%PATH_INDEX%
    set SYNC_TO_PATH_NAME=SYNC_TO_PATH_%PATH_INDEX%
    set SYNC_OPTION_NAME=SYNC_OPTION_%PATH_INDEX%

    rem 形成した変数名の値を取得
    set SYNC_FROM_PATH_LOCAL=!%SYNC_FROM_PATH_NAME%!
    set SYNC_TO_PATH_LOCAL=!%SYNC_TO_PATH_NAME%!
    set SYNC_OPTION_LOCAL=!%SYNC_OPTION_NAME%!

rem ローカル変数を外部に適用するため、外部変数にセット
endlocal && set SYNC_FROM_PATH=%SYNC_FROM_PATH_LOCAL% && set SYNC_TO_PATH=%SYNC_TO_PATH_LOCAL% && set SYNC_OPTION=%SYNC_OPTION_LOCAL%

if "%SYNC_FROM_PATH%" == "" (
    echo [ERROR]SYNC_FROM_PATH未定義:引数=%PATH_INDEX%
    echo [END]%MYSHELL_NAME%
    echo ----
    echo ----
    exit /b %EXIT_CODE_ERROR%
)
if "%SYNC_TO_PATH%" == "" (
    echo [ERROR]SYNC_TO_PATH未定義:引数=%PATH_INDEX%
    echo [END]%MYSHELL_NAME%
    echo ----
    echo ----
    exit /b %EXIT_CODE_ERROR%
)

rem パスの存在チェック
if not exist "%SYNC_FROM_PATH%" (
    echo [ERROR]SYNC_FROM_PATH不正:%SYNC_FROM_PATH%
    echo [END]%MYSHELL_NAME%
    echo ----
    echo ----
    exit /b %EXIT_CODE_ERROR%
)
if not exist "%SYNC_TO_PATH%" (
    echo [ERROR]SYNC_TO_PATH不正:%SYNC_TO_PATH%
    echo [END]%MYSHELL_NAME%
    echo ----
    echo ----
    exit /b %EXIT_CODE_ERROR%
)


rem ****************
rem 同期実行
rem ****************

call .\backupSub.bat "%SYNC_FROM_PATH%" "%SYNC_TO_PATH%" "%SYNC_OPTION%"
if not %errorlevel% == 0 (
    echo [ERROR]同期失敗
    echo [END]%MYSHELL_NAME%
    exit /b %EXIT_CODE_ERROR%
)


echo [INFO]%date% %time%
echo [END]%MYSHELL_NAME%
echo ----
echo ----
exit /b %EXIT_CODE_NORMAL%

backupSub.bat

  • robocopyでバックアップします。オプションはコードの通りです。
  • ログファイルはbackup_schedule_log_日付.txtです。
@echo off

rem ****************
rem バックアップ実行サブバッチ
rem 第1引数:バックアップ元パス
rem 第2引数:バックアップ先パス
rem 第3引数:オプション
rem ****************

rem ログファイル名の生成
set DATE_TMP=%date%
set LOG_SUFFIX=%DATE_TMP:~0,4%%DATE_TMP:~5,2%%DATE_TMP:~8,2%
set LOG_FILE_PATH=%SYNC_LOG_PATH%\backup_schedule_log_%LOG_SUFFIX%.txt

echo [INFO]同期元パス:%~1
echo [INFO]同期先パス:%~2
echo [INFO]オプション:%~3
echo [INFO]ログファイルパス:%LOG_FILE_PATH%

rem robocopyでバックアップ
set RB_CMD_PARAM=%~1 %~2 /mir /copy:DT /z /r:1 /w:1 /xjd /ipg:10 /fft /np /ndl /log+:%LOG_FILE_PATH% /xd "System Volume Information" %~3
echo robocopy %RB_CMD_PARAM%
robocopy %RB_CMD_PARAM%
attrib -H -S %~2

exit /b %EXIT_CODE_NORMAL%