こんな感じの要件を満たしたい。
- ファイルのコピーなれど、ログを残しておきたい。
- ネットワーク経由で別のコンピューターにコピーしたい。
- Windows の標準機能で実現したい。
ロボコピー(ROBOCOPY)でバックアップする。
Robocopy
rpbocopy を使ってみました。
ちなみに「ロバストコピー」って言う、言われ方もあるらしい。猛者向け?
コマンドの構文
ROBOCOPY コピー元 コピー先 [ファイル [ファイル]…] [オプション]
ファイルを指定しなければ、フォルダがコピーの対象になる。
※目的のフォルダへのパスに空のフォルダ(ファイルが含まれない)があると、コピーされずに止まるので「/e」オプション(空のフォルダもコピーする)を指定する。
個人的によく使うサンプル
robocopy^
"<Source directory>"^
"<Target directory>"^
/log:"<logfile path>"^
/e /r:0 /w:0 /np /tee /zオプション
よく使っているものをヘルプから抜粋。
/E
:: 空のディレクトリを含むサブディレクトリをコピーします。
(とりあえず、これ。)
/PURGE
:: 既にコピー元に存在しないコピー先のファイル/ディレクトリを削除します。
/MIR
:: ディレクトリ ツリーをミラー化します (/E および /PURGE と同等)。
(どちらかというと、/L オプションでフォルダ間の比較に使用したりすることが多いかも。)
/L
:: リストのみ – いずれのファイルにも、コピー、タイムスタンプの追加、または削除を実施しません。
/R:n
:: 失敗したコピーに対する再試行数: 既定値は 1,000,000。
/W:n
:: 再試行と再試行の間の待機時間: 既定値は、30 秒です。
/NP
:: 進行状況なし – コピーの完了率を表示しません。
/LOG:ファイル
:: ログ ファイルに状態を出力します (既存のログを上書きします)。
/LOG+:ファイル
:: ログ ファイルに状態を出力します (既存のログ ファイルに追加します)。
/TEE
:: コンソール ウィンドウとログ ファイルに出力します。
/Z :: 再起動可能モードでファイルをコピーします。
(途中で止まっても、再開すると続きから再開してくれる。さすがにファイル単位でだと思うけど。)
フォルダを除外するオプション
/XD ” フォルダ名 ”
例:ユーザーフォルダ丸ごとバックアップ。でも「OneDrive」のフォルダは除外する。
D:\>robocopy C:\Users\unimoni unimoni_221128_3510 /r:0 /w:0 /mir /xd "OneDrive" /log:D:\copy.logローカル環境でテスト
robocopy <source> <destination> <file> [<options>]
robocopy^
"C:\Users\Administrator\Desktop\wallpapers"^
"C:\Users\Administrator\Desktop\test"^
"wallpaperbetter - 2021-04-27T213837.237.jpg"wallpapers フォルダ → test フォルダへ「wallpaperbetter – 2021-04-27T213837.237.jpg」ファイルをコピーする。(オプション指定は無し。)

ネットワーク経由でコピーする為の準備。
お互いにHOSTS ファイルに相手のIP を記述して、名前解決できるように設定する。
ソースサーバー

ターゲットサーバー

ターゲットサーバー側で、コピー先のフォルダに共有をかけておく。
(共有するロールなどを指定してアクセス権を設定する。)
C ドライブとかに共有設定してもいいと思います。

ソースサーバーからアクセスできる。

サーバー間でコピー
丸ごと同期なので、/mir で。あとログ出力も設定した。
ファースト書き込みについては、いきなり「/mir」を使用して指定が反対だったりしたら、全部消えるので「/e」の方が安全。バックアップとかとってる環境じゃないとなかなか怖いっす。
また「/l」でテストできるので、テストもした方がいい。
攻めてる版 ^^;
robocopy^
"C:\Users\Administrator\Desktop\wallpapers"^
"\\wc1202.co.jp\test"^
/w:0 /r:0^
/mir^
/zb^
/log:test.log安心版 ^^
robocopy^
"C:\Users\Administrator\Desktop\wallpapers"^
"\\wc1202.co.jp\test"^
/w:0 /r:0^
/e^
/zb^
/log:test.log
コピーできてる

コピーを実行した時に認証で引っかかるようなら、
robocopy を実行する前に(そのコマンドプロンプトで)「net use」を実行して、認証が済んだ状態にしておく。
エラー例:
エラー 1326 (0x0000052E) コピー元のファイル システムの種類を取得しています \\***\
ユーザー名またはパスワードが正しくありません。net use を実行して認証してからrobocopy を実行する。
net use "コピー先(またはコピー元)" /user:権限のあるユーザー パスワード
ログもイイ感じ。
(/np で進捗% を非表示にできます。結構細かく進捗を返すので、大きいファイルだと無駄なログの塊になるので注意。)


バッチファイル内で日本語やスペースの入ったパスを扱う場合。
パスを現在のディレクトリパスを「set CURDIR=%~dp0」で拾ってコピー元パスを生成してから、コピー先も変数とか使って定義する場合、パスに日本語やスペースが入っていると、robocopy がちゃんと認識してくれない問題。
とりあえずパスを「”(ダブルクォーテーション)」で括れば、日本語もスペースもいいんだけど、変数自体に「”」を持たせておいた方がよさそうです。
あと、最後の「\」を変数にいれてしまうと、最後の「”」がrobocopy の中でエスケープされるみたいなので、最後の「\」なしで、変数に「”」を入れましょう。
「\」を入れるとフォルダを指してくれるので、便利ですが無理そうです。パス自体に「”」を入れると、それ以上は伸ばせないので、順番も考えないとです。
バッチファイルのサンプル
:: 変数からパスを生成
set SD_D1="%CURDIR%Data\D1"
set SD_D2="%CURDIR%Data\D2"
set SD_D3="%CURDIR%Data\D3"
set TD_D1="%folder_name%\%version%\data"
set TD_D2="%folder_name%\%version%\database"
set TD_D3="%folder_name%\%version%\configuration"
:: フォルダパスが存在するか確認。
if not exist %SD_D1% (echo [NG] SD_D1=%SD_D1% & set ERR=1) else (echo [OK] SD_D1=%SD_D1% )
if not exist %SD_D2% (echo [NG] SD_D2=%SD_D2% & set ERR=1) else (echo [OK] SD_D2=%SD_D2% )
if not exist %SD_D3% (echo [NG] SD_D3=%SD_D3% & set ERR=1) else (echo [OK] SD_D3=%SD_D3% )
if not exist %TD_D1% (echo [NG] TD_D1=%TD_D1% & set ERR=1) else (echo [OK] TD_D1=%TD_D1% )
if not exist %TD_D2% (echo [NG] TD_D2=%TD_D2% & set ERR=1) else (echo [OK] TD_D2=%TD_D2% )
if not exist %TD_D3% (echo [NG] TD_D3=%TD_D3% & set ERR=1) else (echo [OK] TD_D3=%TD_D3% )
:: コピー実行。
robocopy %SD_D1% %TD_D1% /e /is /it /r:3 /w:3 /tee /log+:"%CURDIR%log\robocopy.log"
robocopy %SD_D2% %TD_D2% /e /is /it /r:3 /w:3 /tee /log+:"%CURDIR%log\robocopy.log"
robocopy %SD_D3% %TD_D3% /e /is /it /r:3 /w:3 /tee /log+:"%CURDIR%log\robocopy.log"ちなみに最初は、robocopy の変数の方に「”」をつけてたんですが、開始側の「”」が消えるという変な現象が起きてめちゃくちゃはまりました。
ログについて
/tee をつけると、ログファイルへの書き込みつつ、コマンドプロンプトでも表示されます。
/L オプションでプレビュー、ログ書き込みのみ。
お世辞にもわかりやすいログとは言えないが、ないよりマシ。
欲を言えば、コマンドプロンプトで進捗インジケーターつけてほしい。
新しいファイル、新しいフォルダ
ソースと比べてターゲットが古い。または、ターゲットに存在しない。

コピー元、コピー先に存在するファイルで、ソースの方が古い場合は、「古い」になります。
どちらにせよ、差分はコピーされる。
(100% なんでも上書きにするなら、/is /it のオプションも追加する。)
コピー元にないが、コピー先にある。余計?なファイル。
「*EXTRA~」はコピー元にないが、コピー先にあるアイテムを指しているので、
オプションが「/E」か、「/MIR」かで振る舞いが変わってきます。

下記の表記は、先頭の数字がファイル数で、後ろがそのパス。

7 C:\Users\unimoni\AppData\Local\AMD\CN\

エラーになったとき
日本語の場合、「エラー」で検索。
「失敗」の項目が0 でないときも、ログから問題があったファイルを確認できます。

最終結果一覧の数字がズレている件
ズレているのは英語表記にするといいらしい。
chcp 65001
ただ、英語読めないと、何が起きているかもわからないという。
参考:
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/robocopy
https://n-archives.net/software/robosync/articles/robosync-tips-option-l/
その他のファイル操作系のコマンド
copy
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/copy
rmdir , rd
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/rmdir
削除
ディレクトリを削除します。
RMDIR [/S] [/Q] [ドライブ:]パス
RD [/S] [/Q] [ドライブ:]パス
/S 指定されたディレクトリに加えて、そのディレクトリ内のすべての
ディレクトリとファイルを削除します。ディレクトリ ツリーを削除
するときに使用します。
/Q /S を指定してディレクトリ ツリーを削除するときに、確認の
メッセージを表示しません。(QUIET モード)ファイルだとdel
C:\Windows\system32>del /?
ファイル (複数可) を削除します。
DEL [/P] [/F] [/S] [/Q] [/A[[:]属性]] 名前
ERASE [/P] [/F] [/S] [/Q] [/A[[:]属性]] 名前
名前 ファイルまたはディレクトリ (複数可) の一覧を指定します。
複数のファイルを削除するときはワイルドカードを使用します。
ディレクトリが指定されたときはディレクトリ内のすべてのファ
イルは削除されます。
/P 各ファイルを削除する前に確認のメッセージを表示します。
/F 読み取り専用ファイルを強制的に削除します。
/S 指定されたファイルをすべてのサブディレクトリから削除します。
/Q ワイルドカードを使用して一括削除するときに、確認のメッセージ
を表示しません。(QUIET モード)
/A 属性により削除するファイルを選択します。
属性 R 読み取り専用 S システム ファイル
H 隠しファイル A アーカイブ
I 非インデックス対象ファイル L 再解析ポイント
- その属性以外
コマンド拡張機能を有効にすると、DEL と ERASE は次のように変更されます:
/S スイッチの表示形式が逆になり、見つからなかったファイルではなく
削除されたファイルだけが表示されるようになります。rename
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/rename
C:\Windows\system32>rename /?
ファイル (複数可) の名前を変更します。
RENAME [ドライブ:][パス]ファイル名1 ファイル名2
REN [ドライブ:][パス]ファイル名1 ファイル名2
ファイル名2 には新しいドライブもパスも指定できないので注意してください。以上です。