まだHabréにアカウントを持っていない友人のリクエストで記事を公開します。誰かが追加の招待を持っている場合は、evgeny.sementsov [doggie] gmail.comを共有してくださいデータのバックアップに7Zipを使用することに関する記事を読んだ後、自分の「ファイル作品」を書くというアイデアが
生まれました 。
「自転車を発明する」というアイデアは、理由があると言ったに違いありません。 初期段階では、外部ツールを使用することも計画されていました。
経験から生まれた次の要件がありました。
- 無料
- ユーザーには見えないバックグラウンドでのコピー
- バックアップ中にコンピューター上で完全に機能する機能(つまり、バックアップがパフォーマンスに重大な影響を与えるべきではない)
- コピーの目標(ファイル、ディレクトリからレジストリへ)を柔軟に構成する機能、バックアップが必要なユーザー
- ユーザーがバックアップの実行を制御する機能(つまり、中断が最後の手段です)、管理者がバックアップが完了したかどうかを確認する機能。
- 「スマートバックアップ」、つまり 何をコピーするか、何をコピーしないかを決定する(明確な基準を備えた)外出中の能力。 たとえば、Thunderbirdプロファイルがある場合は、The Bat!、プロファイルをコピーしないでください。
- さまざまなユーザーのバックアップの頻度を制御する機能
- バックアップサーバーのチャネルを詰まらせないように、作業時間ごとにバックアップ時間を分散する
- バックアップサーバーを完全にいっぱいにしないように、バックアップの数を管理する機能
- 必要なバックアップを見つけ、必要なファイルを抽出することの容易さ
多かれ少なかれ適切なソリューションに最も近いものは、Cobian Backup、Amandaです。
ほとんどの場合に適していると思います。 しかし、私たちのものではありません。 Active Directoryグループポリシーツールを使用してMSIパッケージを展開する機能がないことを忘れていました。 私たちは長い間SAMBAを使用しています。 なぜなら 必要な設定が内部に組み込まれた代替サイレントサイレントインストーラーを作成し、psexec(管理者としてのサイレントインストールの場合)でそれらをシャーマニングしたくはありませんでした。 ? 一般に、WSHに組み込まれた優れたJavascript言語と、強力な無料の7Zipコンソールアーカイバです。
推論に取りかかりましょう。
段階的に始めましょう。
1)どのユーザーにいつバックアップするかを決定する方法。つまり 1日中、チャネルのブロックを解除したままにします(多くのメールフォルダだけで数ギガバイトを占有します)。
重大ではないエラーが発生した場合、すべてのユーザーにすべての時間を均等に配分することが最善であると想定できます。
バックアップは10〜16に作成する必要があると想定しています。したがって、sambaサーバーでは、すべてのユーザーの数をカウントし、時間間隔を分散します。 これを行うには、winbinddサービスを実行します。
したがって、
set_intervals_for_backup.sh 。
#!/bin/sh
all=`wbinfo -u|wc -l`
wbinfo -u | awk -v all=$all 'BEGIN {i=0;}; {i++; j=int(360*i/all); h=10+int(j/60); m=j%60; print $1" "h" "m}' > /usr/samba/netlogon/intervals.txt
- :
andrey 10 2
boris 10 4
boriska 10 6
cidor 10 8
...
このスクリプトの起動をcronで正しく登録する必要があります。
2)バックアップの作成方法。smb.confで、すべてのユーザーのlogon.batを登録する必要があります。
そして、その中で、順番に:
start wscript \\sambaserver\netlogon\backups_v2.js
backups_v2.js :
//---------------------------------------------- ->
// smb-
var path_for_saving = "\\\\backupserver\\backup\\profiles\\";
// , ,
users = new Array();
users.push('fed');
users.push('sol');
users.push('lanis');
users.push('solod');
//---------------------------------------------- <-
// - ( )
function findU_andExit(thisUser)
{
d = new Date;
if (d.getDate() % 5 != 0)
return;
for (i = 0; i < users.length; i++) // 0,1,2,3,4 possible but it will be only in case "0"
if (users[i] == thisUser)
WScript.Quit();
}
//
function rand(vmin, vmax)
{
if (vmax) {
return Math.floor(Math.random() * (vmax - vmin + 1)) + vmin;
} else {
return Math.floor(Math.random() * (vmin + 1));
}
}
// "" , .. 9 "09".
function d_2(p)
{
var tmp = 0;
if (p)
tmp = (p < 10) ? "0"+p : p;
else
tmp = '00';
return tmp;
}
// ..
function get2FDate()
{
d = new Date();
s = d_2(d.getDate())+'.'+d_2(d.getMonth()+1)+'.'+d.getYear();
return s;
}
// WMI
WMI = GetObject("winmgmts:");
//
function lowPrior(procName)
{
result = WMI.ExecQuery("SELECT * FROM Win32_Process Where Name = '"+procName+"'");
var IDLE = 64;
var colCS = new Enumerator(result);
for (; !colCS.atEnd(); colCS.moveNext())
colCS.item().SetPriority(IDLE);
}
// ,
function countProc(procName)
{
result = WMI.ExecQuery("SELECT * FROM Win32_Process Where Name = '"+procName+"'");
var colCS = new Enumerator(result);
var j = 0;
for (; !colCS.atEnd(); colCS.moveNext())
j++;
return j;
}
//
var WshShell = WScript.CreateObject("WScript.Shell")
var FSO = new ActiveXObject("Scripting.FileSystemObject");
var WshProcEnv = WshShell.Environment("PROCESS");
//
var cn = WshProcEnv("COMPUTERNAME");
//
var un = WshProcEnv("USERNAME");
// -
// ,
// winbindd - HOMEWORK
// nsswitch.conf winbind
// LDAP - ldapsearch ( )
path_for_saving += un;
// -
findU_andExit(un);
//
var up = WshProcEnv("USERPROFILE");
// -------------------- ->
// -
var h1=0;
var m1=0;
ForReading = 1;
f_intervals = FSO.OpenTextFile('\\\\sambaserver\\netlogon\\intervals.txt', ForReading, false);
//
var re = new RegExp("("+un+")\\s(\\d+?)\\s(\\d+?)","ig");
while (!f_intervals.AtEndOfStream)
{
s = f_intervals.ReadLine();
if ((re.exec(s)) != null)
{
h1 = RegExp.$2 * 1;
m1 = RegExp.$3 * 1;
}
}
f_intervals.Close();
// , , 10 16
// , -
if (h1==0 && m1==0)
{
h1 = rand(10,15);
m1 = rand(0,59);
}
//
function chkDate()
{
d = new Date();
if (h1==d.getHours() && m1==d.getMinutes())
return true;
else
return false;
}
// -------------------- <-
// " "
strDesktop = WshShell.SpecialFolders("Desktop");
// " "
strMyDocuments = WshShell.SpecialFolders("MyDocuments");
// , , The Bat!, Thunderbird.
strAppData = up + "\\Application Data";
strTheBat = strAppData + "\\The Bat!";
strThunderBird = strAppData + "\\Thunderbird";
// QIP .
strQIP = up + "\\QIP";
//
var saved_dirs = '';
//
var saveFN = path_for_saving+"\\"+get2FDate()+'_from_'+cn+'.zip';
// ()
var tmp_saveFN = saveFN+'.1';
while (1)
{
// 5 -
WScript.Sleep(5000);
if (chkDate()) //
{
// ,
saved_dirs += "\""+strDesktop+"\" \""+strMyDocuments+"\"";
// - -
try
{
if (FSO.FileExists(tmp_saveFN))
FSO.DeleteFile(tmp_saveFN, true);
}
catch(e)
{
}
// QIP, ; , Thunderbird, The Bat!
if (FSO.FolderExists(strQIP))
saved_dirs += " \""+strQIP+"\"";
if (FSO.FolderExists(strThunderBird))
saved_dirs += " \""+strThunderBird+"\"";
else
{
if (FSO.FolderExists(strTheBat))
saved_dirs += " \""+strTheBat+"\"";
}
//
WshShell.Run("regedit /ea "+path_for_saving+"\\"+get2FDate()+"_HKCU.reg HKEY_CURRENT_USER", 0, false);
// - ( ),
// - 7Zip.
WshShell.Run("\\\\sambaserver\\netlogon\\7za.exe a -tzip "+tmp_saveFN+' '+saved_dirs+' -ssw -mx1 -mmt -mm=Deflate', 0, false);
// -
WScript.Sleep(7500);
lowPrior('7za.exe');
while (1)
{
// - 7za
// - 7za,
// , , , , , ,
// ..
WScript.Sleep(1000);
if (countProc('7za.exe') == 0)
{
try
{
// ,
if (FSO.FileExists(saveFN))
FSO.DeleteFile(saveFN, true);
FSO.MoveFile(tmp_saveFN, saveFN);
}
catch(e)
{
}
// -
WScript.Quit();
}
}
}
}
3)バックアップの実行を管理する方法。ユーザー向けの簡単なスクリプトを書きました。
backups_STOP_NOW.js :
var WMI = GetObject("winmgmts:");
var WshShell = WScript.CreateObject("WScript.Shell");
var IMname = "7za.exe";
var result = WMI.ExecQuery("SELECT * FROM Win32_Process Where Name = '"+ IMname + "'");
var j = 0;
var colCS = new Enumerator(result);
for (; !colCS.atEnd(); colCS.moveNext())
j++;
if (j>0)
{
var BtnCode = WshShell.Popup(" . ?", 0, " ", 4 + 32);
switch(BtnCode)
{
case 6: //yes
WshShell.Run("taskkill /IM " + IMname);
break;
}
}
4)バックアップでストレージを管理する方法。
サーバーの容量により、最後の3つのバックアップを保存できました。
ここで、「追加」バックアップをクリーンアップする管理マシンから実行するスクリプトを提供します。
それを「タスクスケジューラ」に入れて、バックアップストレージのあるフォルダーに書き込み権限を持つユーザーの下で実行するだけです。
clear_old_backups.js :
fso = new ActiveXObject("Scripting.FileSystemObject");
//
function diffDates(a1, a2)
{
//31.08.2009 => 20090831
a1 = fso.GetBaseName(a1);
a2 = fso.GetBaseName(a2);
var t1, t2;
t1 = a1.substr(6,4)+a1.substr(3,2)+a1.substr(0,2);
t2 = a2.substr(6,4)+a2.substr(3,2)+a2.substr(0,2);
t1 = t1 - 0; t2 = t2 - 0;
if (t2 > t1)
return 1;
else
return 0;
}
//
function ShowFolderList(folderspec)
{
var f, fc;
var p;
var ar;
var foldername = fso.GetFileName(folderspec);
// .zip .reg
// , ""
var r = new Array(/\.zip/i, /\.reg/i);
f = fso.GetFolder(folderspec);
//
// , ,
for (k in r) // for .zip, .reg
{
ar = new Array();
fc = new Enumerator(f.Files);
for (; !fc.atEnd(); fc.moveNext())
{
p = fc.item();
if (r[k].test(p))
ar.push(p);
}
// ,
// , ,
ar = (ar.toString()).split(",");
//
var tmp;
for (i=0; i < ar.length-1; i++)
for (j=i+1; j < ar.length; j++)
if (diffDates(ar[i],ar[j]))
{
tmp = ar[i];
ar[i] = ar[j];
ar[j] = tmp;
}
// 3
for (i=3; i < ar.length; i++) //0, 1, 2 will be
{
try
{
fso.DeleteFile(ar[i], true);
}
catch(e)
{
}
}
}
}
// ""
var d = fso.GetFolder("\\\\backupserver\\backup\\profiles");
fc = new Enumerator(d.SubFolders);
for (; !fc.atEnd(); fc.moveNext())
{
ShowFolderList(fc.item());
}
5)要約するそのため、最終的には、まさに望みどおりの結果を達成しました。 バックアップは.zip形式で作成され、アーカイバプログラムによって開かれます。
7-zip.orgで7za.exeを見つけるのに問題がないことを願っています。
この場合、ユーザー自身がバックアップから必要なファイルを取得できます。これは(管理者がいない場合)プラスです。
あなたのコメントを待っています! これはHabréに関する私の最初の投稿であり、最後ではないと思います。 残念ながら、アカウントを持っていないので、コメントを書くことはできません(現時点では)。