Boxへのデータ移行バッチ

業務で利用したファイルサーバーからBoxへのデータ移行バッチのソースコードを公開します。

Boxデータ移行バッチの機能要件

  1. 移行元フォルダと移行先フォルダを指定すると、移行元フォルダのサブフォルダを含むすべてのファイルをコピーする。
  2. 移行除外したいフォルダ名を指定することで指定された文字列を含むフォルダ以下のファイルやサブフォルダはコピーしない。
    • 「old」や「backup」という文字列を含むフォルダを移行対象から除外できます。
  3. Boxに移行できない以下のファイル・フォルダはコピーしない。
    • システムファイル
    • 隠しファイル
    • 隠しフォルダ
    • テンポラリファイル(拡張子がtmp、チルダ「~」で始まるファイル)
    • Windowsショートカット
    • OutlookのPSTファイル
    • Quickbooksファイル
  4. 移行元フォルダをコピーするかどうかを指定できる。
    • 移行元フォルダの構成が以下の場合に移行先フォルダに「original」というフォルダを作成し、そのサブフォルダとして「folder1」と「folder2」を作成するかどうかを指定できます。
      • ./original/
        • └folder1/
        • └folder2/

Boxデータ移行バッチ利用にあたり前提条件

  1. Box Driveをインストールしてください。
    • Box DriveはBox, Inc.が提供するエクスプローラーでBoxの操作を行えるようにする無償のアプリケーションです。
  2. Windowsのコマンドは失敗する場合があります。必ず出力されるログを確認し移行できなかったフォルダやファイルに対し適切な処置をお願いします。
  3. 大量のフォルダ、ファイルを移行する前に数件程度のフォルダでバッチの挙動をお確かめください。
  4. その他の免責事項などはプライバシーポリシーをご確認ください。

ソースコード

@echo off
setlocal enabledelayedexpansion

REM コピー元ディレクトリを設定
set "source_directory=%~1"

call :GET_BASE_DIRECTORY "%source_directory%" directory

REM コピー元ディレクトリごとコピーする場合
if "%~4" == "1" (
	set "copy_base_directory=!directory!"
)

REM コピー先ディレクトリを設定
set "destination_directory=%~2"

REM コピー除外するディレクトリの文字列(複数)を設定
set "exclude_directory_strings=%~3"

REM コピー元ディレクトリ内を再帰的に検査
for /r "%source_directory%" %%D in (*) do (
	REM ディレクトリパスを設定
	set "directory_path=%%~dpD"

	REM 「コピーするディレクトリである」を設定
	set "can_exclude_directory=0"

	for %%E in (%exclude_directory_strings%) do (
		REM ディレクトリパスにコピー除外するディレクトリの文字列が含まれる場合
		echo !directory_path! | find /i "%%E" > nul && (
			echo △ [!directory_path!]除外ディレクトリ
			REM 「コピーしないディレクトリである」を設定
			set "can_exclude_directory=1"
		)
	)

	REM ディレクトリをコピーする場合
	if "!can_exclude_directory!" == "0" (
		call :GET_DESTINATION_DIRECTORY_PATH "!directory_path!" destination_sub_directory

		if not exist "!destination_sub_directory!" (
			REM コピー先ディレクトリを作成
			mkdir "!destination_sub_directory!"

			if errorlevel 0 (
				echo ○ [!destination_sub_directory!] ディレクトリ作成成功
			) else (
				echo × [!destination_sub_directory!] ディレクトリ作成失敗
			)
		)
	)
)

REM コピー元ディレクトリ内を再帰的に検査
for /r "%source_directory%" %%F in (*) do (
	REM ファイルパスを設定
	set "file_path=%%~dpF"

	REM ファイルの属性を設定
	set "file_attributes=%%~aF"

	REM 属性がディレクトリではない場合
	if "!file_attributes:~0,1!" neq "d" (
		if /i "%%~xF"==".lnk" (
			REM 拡張子がショートカットの場合はコピーしない
			echo △ [%%~F] ショートカット
		) else if /i "%%~xF" == ".pst" (
			REM 拡張子が Outlook データファイルの場合はコピーしない
			echo △ [%%~F] Outlook データファイル
		) else if /i "%%~xF" == ".ost" (
			REM 拡張子が Outlook データファイルの場合はコピーしない
			echo △ [%%~F] Outlook データファイル
		) else if /i "%%~xF" == ".qbo" (
			REM 拡張子が Quickbooks ファイルの場合はコピーしない
			echo △ [%%~F] Quickbooks ファイル
		) else if /i "%%~xF" == ".qbw" (
			REM 拡張子が Quickbooks ファイルの場合はコピーしない
			echo △ [%%~F] Quickbooks ファイル
		) else if /i "%%~xF" == ".tmp" (
			REM 拡張子が Temporary ファイルの場合はコピーしない
			echo △ [%%~F] Temporary ファイル
		) else (
			set "first_file_str=%%~nF"
			if "!first_file_str:~0,1!" neq "~" (
				call :GET_DESTINATION_DIRECTORY_PATH "!file_path!" destination_sub_directory

				REM コピー先ディレクトリが存在する場合
				if exist "!destination_sub_directory!" (
					copy "%%~F" "!destination_sub_directory!" /Y

					if errorlevel 0 (
						echo ○ [%%~F] ファイルコピー成功
					) else (
						echo × [%%~F] ファイルコピー失敗
					)
				) else (
					echo △ [%%~F] コピー先ディレクトリなし
				)
			)
		)
	)
)

echo ファイルのコピー処理が完了しました。
goto :EOF

:GET_BASE_DIRECTORY
setlocal
	REM フルパスを設定
	set "full_path=%~1"

	REM フルパスの最後の一文字を設定
	set "path_last_charactor=!full_path:~-1,1!"

	REM フルパスの最後の一文字が「\」の場合は削除
	if "!path_last_charactor!" == "\" (
		set "full_path=!full_path:~0,-1!"
	)

	for %%I in ("!full_path!") do (
		set "base_directory=%%~nxI"
	)
endlocal & set "%~2=%base_directory%"
goto :EOF

:GET_SOURCE_DIRECTORY_RELATIVE_PATH
setlocal
	set "full_path=%~1"
	set "relative_path=!full_path:%source_directory%\=!"
endlocal & set "%~2=%relative_path%"
goto :EOF

:GET_DESTINATION_DIRECTORY_PATH
setlocal
	set "destination_directory_path=%destination_directory%"

	if defined copy_base_directory (
		set "destination_directory_path=!destination_directory_path!\%copy_base_directory%"
	)

	call :GET_SOURCE_DIRECTORY_RELATIVE_PATH "%~1" relative_path

	set "destination_directory_path=!destination_directory_path!\!relative_path!"
endlocal & set "%~2=%destination_directory_path%"
goto :EOF

バッチの引数

  • 第1引数:移行元フォルダの絶対パス
  • 第2引数:移行先フォルダ(Box)の絶対パス
  • 第3引数:移行除外するフォルダに含まれる文字列
    • 半角スペース区切りで複数指定することが可能です。
  • 第4引数:移行元フォルダをコピーする場合は「1」、それ以外は「0」

バッチ実行シグネチャー

バッチの名前を「copy_to_box.bat」、「C:\Users\xxx\OneDrive\bats\org」から「C:\Users\xxx\OneDrive\bats\dest」に「org」フォルダごとコピーするが「old」または「backup」を含むフォルダのコピーは行わない。バッチの実行結果を「copy.log」に追加する場合は以下のように記述します。

除外したいフォルダがない場合はバッチの第3引数を""にしてください。

copy_to_box.bat "C:\Users\xxx\OneDrive\bats\org" "C:\Users\xxx\OneDrive\bats\dest" "old backup" 1 >> copy.log

Follow me!

photo by:Todd Trapani