ファイルサーバーの引っ越しがあるそうな。作業用IDでアクセス権のないファイルは一括で移行できないからそこは各自がやっといて、とのこと。当然のことだが、では作業用IDのアクセス権グループがついてないのはどれ?を調べないといけない。フリーソフト開発秘話、目次へ
ついでに言うと「あれ、そんなファイルがあるとすれば、作業用IDではバックアップがとれないってことだよなあ」と気が付いたのだが、大問題なので黙っていた。
調べる一番簡単な方法は「移行できなくて困るファイルのアクセス権、各自が調べておいて」。というわけで皆さん延々ファイルを右クリックしてプロパティを開き、「セキュリティタブを見て」ということをやることになる。実はこれが一番正しい。困る人が責任を持つ、なんと公平なやりかたであろうか。しかしこれでは会社組織にしたメリットが相当減殺されるので、一括でやれないかと考えた。
ファイルサーバーはNTFSなので、よーするに各ファイルについてicaclsコマンドを発行して、戻ってきた値を見て該当アクセス権があるかどうか見ればよい。問題はこのicaclsコマンドを発行する対象のファイルをいちいち探しに行かなければならないということである。少々ややこしいが説明すると、
icaclsコマンドを発行できるためには、当該のファイルが自分から見えないといけない。つまり自分がアクセス権を持っていないフォルダに入ったファイルはicaclsコマンドでアクセス権を調べることはできないのだ。いかにもそういうファイルにこそ、独自にアクセス権が設定されており、つまり作業用IDからも見えなくなっていそうではないか。
というわけで、再帰的にディレクトリをたどってゆき、自分のアクセス権が無くなったところで「このフォルダは調べられないからアクセス権のある人が見てね」というワーニングを出さないといけない。ようするにDIRコマンドで出力したファイル一覧を元にicaclsコマンドを発行してもあまり意味がないということだ。dirではアクセス権のないフォルダは見えないのだから。
かくしてこの一回こっきりの調査用に、恐ろしく時間のかかるツールが書かれた。(書いたのは自分だが壮大さを考えるとなんか「書かれた」と表現したくなるのだ。)
何日も何日も動き続けた。途中コマンドの結果が返ってこなかったファイル/フォルダについては、作成者の方に連絡が飛んだ。それにしてもどうして他の部署は欲しがらないのだろう。(1件だけ照会があった。まじめに仕事をしようとしている人がいるのだろう。)こいつはただ一回の使命を終えて安らかな眠りについていたのだが、数年後、引っ張り出されることになった。「アクセス権がなくて、配下のファイルフォルダを調べられないフォルダ」を探してチェックしておく必要があるんじゃないかなあ、という気になったのである。もう一回あれを走らせるとなると膨大な時間が必要になるが、、、でも今度はファイルごとでなくてフォルダだ。数は少ない。何とかなるだろう。
当初は、まあ3日もあれば結果は出る、だったがファイルはどんどん増えて増えて、とても処理しきれなくなった。まあ念のため、ということでサービスで出してたんだし、やめてもいいか、とあきらめました。すると「ないと困るんだけど」という人が。「そんなのアクセス権設定する側の責任者に問い合わせるべきでしょ」と正論を言ってお引き取り願ったが、なるほどアテにしてくれていた人がいたのか、ならなんとかしたいね。
確かに以前と違って「作業用IDでアクセスできるかどうか」でなくて、「あたしがアクセスできるかどうか」が分かればいい。icaclsコマンドを使わなくていいなら、もっと速くできるかもしれない。
途中で気が付いたがDIRコマンドで「フォルダのみ表示」とした出力が使える。確かにDIRコマンドに/sスイッチを付けて再帰的に出力すると、自分がアクセスできないフォルダについては、その下の階層は分からない。コマンドの出力結果に「アクセス権がない」と出てこないのでどうしようもない。しかしながら一階層上のフォルダでDIRやったとき、サブフォルダ名としては出てくるわけだ。したがって「サブフォルダとして表示されるが、直接DIRの対象とならないフォルダ」を一覧化すれば、それが私が中身が分からないフォルダ。これについての調査を各自にお願いすればいいわけだ。dir /ad /sの出力を読み込んで
存在が見えるフォルダ群とアクセス権があるフォルダ群の2つの集合を作り、互いの差分をだせばよろしいことになる。めんどくさいができないわけではない。
(ここで常に「存在が見える」⊃「アクセス権がある」を仮定しないのが私。)初期バージョン:終わらない。一つ一つぶつけてるもんだから数万×数万だとこうなるのも当たり前。これほどかかるとは思わなかったけど。
というわけで、存在が確認されたアクセス権のあるフォルダについては、一覧表から消してゆくことにした。すんごくかかるけども、まあ許容できなくはない。セルを消してゆくという動作に時間がかかるんだな。下から消してゆくようにして極力負荷が無いようにしたのだが。とりあえず暫定完成版。所要時間1時間22分。
完了分を消しこむ、だとこれ以上速くなりそうもないので、新ロジックを編み出した。ソートマージの変形なのだが、ようするに双方のフォルダ名をA列とB列に並べて2つの列のうち片方にしかないものに色を付ける、というもの。結構考えるのがめんどくさいのだぞ。ついつい教科書的マージロジックに引きずられるものだからね。結局永久ループを作って、データを全部出力すると強制脱出なんて気味の悪いロジックにせざるを得なかった。しかしワークシートのソートと、VBAの大小比較では順序が違うとは・・・MS-Excelおそるべし。(暫定完成版は「=」だけを気にすればよかったが、今回は大小比較が入ってくるので、その分デリケートになる。)所要時間はわずか1分23秒にまで縮まった。
MS-Excelのワークシートにおけるソートは飛びぬけて速い、のでフォルダ名をシートに展開したが、その気になったらもっと早くできねえか?とさらなる挑戦。比較している「存在が見えるフォルダの一覧」と「アクセス権のあるフォルダの一覧」は、まず配列に読み込んでいるので、そのままクイックソート。ソートマージもどきで(ソートマージと違って双方の配列に対してロジックが対称である)、不一致があったレコードのみワークシートに出力とした。
所要時間24秒。実に200倍の速度となった。