2017年6月13日火曜日

ROBOCOPYでアクセスが拒否されましたが表示される

 最近、システムの入替作業を進める中で、業者からROBOCOPYなる使えるユーティリティがあることを教わった。使ってみるととても便利だ。今まではXCOPYでサーバー間のファイルコピーをしていたが、ROBOCOPYの方が元々そういった目的で開発されたユーティリティらしく機能も豊富だ。

 使用しているうちに欲が出てきて、このROBOCOPYを使ってバックアップもしたくなった。パラメーターを指定してバックアップを実行すると、殆どのファイルのバックアップは正常に終了するのだが、一部のファイルに”エラー 5 (0x00000005) ファイルをコピーしています・・・アクセスが拒否されました。”なるエラーメッセージが表示されバックアップが出来ないものがある。

 教えてくれた業者も詳しくはないらしく、周りにも詳しい人間が居ないのでネットで解決策を探した。殆どの問題は解決できたが、一部の問題については解決策が見つからない中、自分なりの方法で解決できたのでご紹介。

・環境
SV1:Windows Server 2012 R2
SV2:Windwos Server 2008 R2
SV3:TeraStation ※このTeraStationが曲者だった。

SV1上でROBOCOPYを起動し、SV2に保存されているデータをSV3へミラーリングコピーする。


・実行したコマンド
set logfile1=C:\HOGE.LOG
set src1=A:\HOGE1
set dest1=B:\HOGE2

robocopy %src1% %dest1% /b /s /purge /copy:DT /R:1 /W:30 /fft  /log+:%logfile1%

※コピーが失敗したので変更した引数
copy:DT 最初にcopy:DATで実行したらエラーが発生。TeraStationにはファイルの属性をコピー出来ない様なのでcopy:DTに変更した。


・結果
殆どのファイル(350,803/350,806件)は正常にコピーが完了しているのに、一部のファイル(3/350,806件)でエラーが発生している。例えば、
2017/06/09 03:10:13 エラー 5 (0x00000005) ファイルをコピーしています A:\HOGE1\構成\2017.6.7構成リスト.xls
アクセスが拒否されました。


・調査
 ”アクセスが拒否されました。”って何?だって、ROBOCOPYを実行しているログインIDでファイルが開ける。開けるのにアクセスが拒否されましたとはどういうこと???? 
UACも無効にしてあるのに。※UACを無効にしている理由はネット上に沢山書き込んであるので割愛。因みに、UACを無効にしていないと以下の手順を実施してもダメな可能性がある。私は試していないので分からないが。

 試しに、複写先をNTFSでフォーマットされたHDDに変更してみると正常にコピーが完了する。どうやらTeraStaionがらみの様だ。

 ファイルのプロパティでセキュリティ情報を表示しても問題なし。しかし、ここで全般情報を表示するとこんなメッセージが。
セキュリティ:このファイルは他のコンピューターから取得したものです。このコンピューターを保護するため、このファイルへのアクセスはブロックされる可能性があります。

 ”ブロックされる可能性があります。”なんて書いてある。原因はこいつか?早速、「ブロックの解除」クリックして解除してみる。その後、ROBOCOPYコマンドを実行すると正常にコピー出来た。やはりこいつが原因かも。しかし、このセキュリティが表示されるファイルは沢山ある。沢山ある中のたった3つだけがエラーするとは流石は”可能性がある”と書いてあるだけの事はあるな。


・対処
 このセキュリティの情報はNTFSの代替データ・ストリーム(ADS)と呼ぶそうだ。ADSについてはネットで調べてもらうとして、今回のコピーが失敗した原因はこのADSをTeraStaionにコピー出来ないことが原因の様な気がする。だってTeraStaionのフォーマット形式はXFSでありNTFSではないから。ならばこのADSを削除してやればコピーは上手くいくかもしれない。そんなときに便利な、ADSを一気に削除するコマンドが存在する。

 そのコマンドはStreams。これもネットで入手可能。私が使用したstreamsはバージョン1.60

 コマンドプロンプトを開いて、A:\HOGE1に移動し、実行したコマンドがこれ。
 streams -d -s *

 引数の意味
 -d メイン・データ・ストリーム以外のストリームを削除。
 -s サブフォルダも再帰的にスキャンする。

 このコマンドを実行後、再度ROBOCOPYコマンドを実行したらエラーは発生しなかった。

 ROBOCOPYを起動するバッチの先頭にこのStreamsコマンドを追加し、コピー前にはADSを削除する様にして解決。

 因みに、当社のサーバーでstreamsを実行してみたら、ADSとして、:Zone.Identifier、:OECustomProperty(拡張子が.eml)、:encryptable(ファイル名がThumbs.db)が存在していた。

2017/07/07 追記
無限ループに陥らないように、コマンドに一つオプションを追加
robocopy %src1% %dest1% /b /s /purge /copy:DT /R:1 /W:30 /fft /log+:%logfile1% /xj