【Windows】robocopyでコピー先フォルダが非表示になる原因と直し方|ドライブのルートをコピーした時

スポンサーリンク
Windows
スポンサーリンク

Windowsのバックアップ機能で、PCのバックアップを外付けのUSBディスク(Bドライブ)に取っていた。ただ、バックアップがそのディスク1台にしかないのが気になったので、PCに内蔵しているほとんど使っていないHDD(Gドライブ)に、robocopyでバックアップのコピーを取ることにした。

ところが、robocopyのログを見るとコピーは終わっているのに、コピー先のG:\Bドライブフォルダがエクスプローラーに表示されない。

結論から書くと、ドライブのルート(B:\)をコピー元にすると、コピー先のフォルダに「隠し」と「システム」の属性が付くのが原因だった。robocopyの後にattrib -s -hで属性を外せば表示される。あわせて、このバッチを「管理者として実行」しないと動かなかった理由も、当時のログから分かったので書いておく。

原因:ドライブのルートには隠し属性とシステム属性が付いている

Microsoftのrobocopyのドキュメントにも、次のように書かれている。

デバイスの ルート からデータがコピーされた場合、コピー先ディレクトリはコピープロセス中に「hidden」属性と「system」属性を採用します。

NTFSのドライブのルートには、もともと隠し属性とシステム属性が付いている。robocopyはフォルダの属性もコピーする(/DCOPYの既定値はDAで、Aが属性)ので、コピー先のフォルダも隠しフォルダ・システムフォルダになる。エクスプローラーは初期設定ではこの2つの属性が付いたフォルダを表示しないので、フォルダが消えたように見える。中身はちゃんとコピーされていて、アドレスバーにパスを直接入力すれば開ける。

私はこの現象をRobocopyでコピー先フォルダが非表示になる - n-Archives.netで知った。

直し方:attribで隠し属性とシステム属性を外す

コピー先のフォルダに対して、次のコマンドを実行する。

attrib -s -h "G:\Bドライブ"

-sがシステム属性、-hが隠し属性を外すオプションだ。Microsoftのattribのドキュメントにあるとおり、システム属性や隠し属性が付いていると、ほかの属性を変える前にそれを外す必要があるので、-sと-hは必ず一緒に指定する。

robocopyを実行するたびにまた属性が付くので、私はバッチファイルの中でrobocopyの直後にattribを実行するようにした。

実際に使っているバッチファイル

今使っているバッチファイルがこれだ(ログの保存先のNAS名だけ<NAS>に置き換えている)。

set srcfolder="B:"
set dstfolder="G:\Bドライブ"

set logfolder="\\<NAS>\backup\バックアップ用ツール\BtoGドライブロボコピー\log"
set logfile=%logfolder%\%date:~0,4%-%date:~5,2%-%date:~8,2%_datacopy.log

robocopy "%srcfolder%" "%dstfolder%" /MIR /DCOPY:DAT /COPYALL /IT /B /log+:"%logfile%" /np /R:3 /W:3
attrib -s -h "%dstfolder%"
forfiles /P "%logfolder%" /M "*.log" /D -93 /C "cmd /c del @file"

やっていることは次の3つだ。

  • 7行目:BドライブをGドライブの「Bドライブ」フォルダにミラーリングする(/MIRはコピー元にないファイルをコピー先から消すので、コピー先のフォルダを間違えないこと)
  • 8行目:コピー先フォルダの隠し属性とシステム属性を外す
  • 9行目:93日より古いログを消す

ログのファイル名に使っている%date:~0,4%などは、日付が2024/01/04の形で表示される環境を前提にしている。

ちなみに、ローカルのフォルダをNASにバックアップするPowerShell版のスクリプトは、RobocopyでローカルフォルダのデータをID/パスワード付きのNASにバックアップするに書いた。

管理者として実行しないと動かなかった理由

このバッチは、ダブルクリックで普通に実行するとうまくいかなかったので、「管理者として実行」にチェックを入れたショートカットを作って、そこから実行している。

バッチファイルのショートカットのプロパティで「詳細設定」から「管理者として実行」にチェックを入れた画面

ショートカットのプロパティの「ショートカット」タブで「詳細設定」を押し、「管理者として実行」にチェックを入れると、ダブルクリックするだけで管理者として実行されるようになる(実行のたびにユーザーアカウント制御の確認は出る)。

なぜ管理者権限が必要だったのか、理由はもう覚えていなかった。今回、当時のログを見返すと、2024年1月4日の実行で次のエラーが出て、コピーが始まる前に止まっていた(その30秒ほど後の実行は、最後まで終わっていた)。

エラー: 監査管理のユーザー権利がありません。

原因は、バッチに付けていた/COPYALLだ。Microsoftのドキュメントによると、/COPYALLは/COPY:DATSOUと同じで、最後のUは「監査情報」のコピーを表す。監査情報を扱うには「監査とセキュリティ ログの管理」(SeSecurityPrivilege)というユーザー権利が必要で、この権利は既定ではAdministratorsグループにしか与えられていない。

また、/B(バックアップモード)は、ファイルやフォルダのアクセス許可を無視してコピーするモードだ。こちらで使う「ファイルとディレクトリのバックアップ」(SeBackupPrivilege)の権利も、既定ではAdministratorsとBackup Operatorsにしか与えられていない。

管理者のアカウントでサインインしていても、「管理者として実行」しないプログラムはこれらの権利を使えない。管理者として実行しないとうまくいかなかったのは、これが理由だと考えられる。

なお、/COPYALLを/COPY:DAT(データ・属性・タイムスタンプだけ)にすれば、監査情報の権利は不要になる。ただ、/Bも外すと、アクセス許可で読めないファイルがコピーできなくなる可能性がある。私はこの組み合わせを試していないので、変える場合は/L(一覧だけ表示してコピーしない)で動きを確かめてからにしてほしい。

まとめ

  • robocopyでドライブのルート(B:\など)をコピーすると、コピー先フォルダに隠し属性とシステム属性が付いて、エクスプローラーに表示されなくなる
  • robocopyの後にattrib -s -h "コピー先フォルダ"を実行すれば表示される。バッチに入れておくと毎回直せる
  • /COPYALL(監査情報のコピー)や/B(バックアップモード)を使うと、管理者として実行しないと動かない。ショートカットの「管理者として実行」を使うと楽

参考

コメント

タイトルとURLをコピーしました