ネットワークドライブにログインしてファイルをコピーする。
この PowerShell 全盛の時代( MS テクノロジー使いに限る)に誰得だとは思いますが、弊社のとあるサーバーには PowerShell が 1 も 2 も入っていないので、仕方なく WHS と JavaScript で書いたので晒しておきます。
ぶっちゃけ自信無い。動いているからよしとしてるけど。
やりたいのは Logs みたいなフォルダに各アプリのログファイルがとある規則で配置されてるので、その前日分を根こそぎコピーしちゃおういという事です。
Logs + App1 + + App1_yyyy-MM-dd.log + + App2 + App2_yyyy-MM-dd.log
前日のログファイル名を取得
ってことをしたいわけですね。
前日を取得
/** * 指定の日付(Date型)に対して日付の加算を行います。 * * @param dt * @param addDays 加算日数 (マイナスで過去) */ function computeDate(dt, addDays) { var baseSec = dt.getTime(); var addSec = addDays * 86400000; var targetSec = baseSec + addSec; dt.setTime(targetSec); return dt; } var today = new Date(); // 今日 var yesterday = computeDate(today, -1); // 前日日付取得
フォーマットしとく
/** * 指定の長さと文字で対象の文字列を左埋めします。 * * @param s 対象の文字列 * @param l 埋める長さ * @param pad 埋める対象の文字 */ function lpad(s,l,pad){ var pads=''; pad=(pad==undefined)?' ':pad; for(var i=0;i<l;i++)pads+=pad; s=pads+s; return s.slice(s.length-l); } var formatted = lpad(yesterday.getFullYear(), 4, 0) + '-' + lpad(yesterday.getMonth() + 1, 2, 0) + '-' + lpad(yesterday.getDate(), 2, 0); // => 2010-12-08
まあ、後はフォルダ名とかを適当に結合すれば前日日付のログファイル名を取得できるってわけですね。
Logs 以下のフォルダ名を取得する
まずは Logs フォルダのオブジェクトを取得しましょう。
var fso = new ActiveXObject("Scripting.FileSystemObject"); var of = fso.GetFolder("C:\\Logs"); // C ドライブ直下にあるとして
ちなみに、バッチの実行場所が Logs フォルダの直下であるなら以下でもOK。
/** * pwd */ var pwd = function() { var sh = WScript.CreateObject("WScript.Shell"); var dir = sh.CurrentDirectory; return function() { return dir; }; }(); var of = fso.GetFolder(pwd());
次に Logs フォルダ直下のフォルダ一覧を取得しましょう。
var subfolders = new Enumerator(of.SubFolders); // ログフォルダを全て取得 for (;!subfolders.atEnd();subfolders.moveNext()) { var filename = subfolders.item().Name; // フォルダ名 }
参考サイト
さて、これで全てのフォルダに対してのループ処理が書けました。
後はコピー処理だけですね。
その前にネットワークドライブに接続する必要がありました。
ネットワークドライブに接続する
すでに接続されている場合はやりません。
var nwo = new ActiveXObject("WScript.Network"); if (!fso.DriveExists("Z:")) nwo.MapNetworkDrive("Z:", "\\\\192.168.x.x\\\targetFolder", false, "username", "password"); // ネットワークドライブに接続
そして切断もちゃんとやりましょう。すでに接続されている場合も切っちゃいましょうか。
nwo.RemoveNetworkDrive("P:"); // ネットワークドライブ切断 nwo = null;
ネットワークドライブへのコピー
まずはコピー対象のローカルファイルがあるか
if (!fso.FileExists(fromPath)) // fromPath はローカルのコピー対象ファイルのパス continue; // コピー対象が存在しなければスキップ
コピー先フォルダが無ければ作る
if (!fso.FolderExists(fileCopyTo)) // fileCopyTo はコピー先フォルダ名 fso.CreateFolder(fileCopyTo);
コピー実行
fso.CopyFile(fromPath, toPath, true); // 第三引数 true で強制上書き
問題
ネットワークドライブへの接続で、共有リソースへのアクセスに同じアカウントでアクセスできないみたいな事を言われて拒否される事がある。「net use /delete」で接続を全て切っても言われ続けるので、たぶん私が何か勘違いしているものと思われる。