'==========================================================
'
' ファイルバックアップスクリプト
' V1.1 kan.massa@gmail.com
' 2009.4
' 2009.5 コメント修正&追記
'
'----------------------------------------------------------
'【機能概要】
'PC内、サーバ→NAS、NAS→PC、PC→PC間のコピーのユーティリティです。
'全ファイルコピーだと時間がかかります。デジカメの写真の
'バックアップも大変ですよね。全部だと・・・・。
'
'ってことで
'
'・ある一定期間に更新があったものを全部コピー
'・同名ファイルがある場合はファイル(更新日時、サイズ)比較
' を実施して違う場合はコピー
' (ディレクトリ一致&ファイル一致)
'
'というユーティリティを作ってみました。
'
'そのままでは芸が無いので・・・
'・タスクスケジューラに仕掛けて動作させる事(画面なし)
'・バッチファイルより起動し進捗がわかるもの
'・同名ファイルの場合コピー先のファイルをリネーム
'
'を用意しました。
'またバックアップが取れているか不安になる方のために
'・ログファイル出力
'
'があります。
'----------------------------------------------------------
'【このソフトウェアに関して】
'フリーウェアです。内容は変更して頂いても構いません。
'ただし小生は動作保証はしません。(当たり前か・・・)
'仕事等楽にしてください。
'著作権は放棄するつもりはありませんので何かに載せたりする
'場合は、ご連絡ください。
'プログラムの勉強に使ってもらえたら最高です!
'==========================================================
'--グローバル変数定義---------------------------------
Dim fso,outfile
Dim backupfoldername
Dim backupsakifoldername
Dim logfolder
Dim logfilename
Dim targetdate1
Dim targetdate2
Dim n
Dim cntfiles
Dim MsgOut
Dim MsgOutMode
Dim foldercnt
Dim ChkMode
Dim BackupMode
Dim logmode
Dim objdic2,objdic3
Dim anytemp
Dim gosa
'--------------------------------------------
' ユーザーセッティングエリア
' ここから変更可能↓
'--------------------------------------------
'------------
'
'バックアップ設定
'
'バックアップ元フォルダ
' ・バックアップしたいフォルダを指定
backupfoldername = "D:\digitalc"
'バックアップ先フォルダ
' ・バックアップを保存するフォルダを指定
backupsakifoldername = "Z:\digitalc"
'バックアップ方法
'1・・・・・一定期間のファイルを強制コピー
' (※旧ファイルのバックアップ機能は動作しません。)
'2・・・・・バックアップ先との差分があるものをコピー
' ・ディレクトリまで一致している場合コピーしない
'3・・・・・バックアップ先との差分があるものをコピー
' ・対象ディレクトリのどこかにファイルがある場合はコピーをしない
' ・存在しない場合はバックアップ元のディレクトリ構造でコピーする
ChkMode = "1"
'同名のファイルが存在し、かつ相違と判定されたらバックアップするか?
' ・ChkMode = "2","3"でのみ有効
' ・同名のファイルは「ファイル名_(更新年月日日時秒).拡張子」とされます。
'0・・・バックアップしない。
'1・・・バックアップする。
BackupMode = "1"
'ファイルの作成日時秒の許す誤差(秒)
' ・ファイルをコピーするとなぜか誤差が出てしまうWindows。+-何秒までを同一ファイルと
' 認定するか指定します。
gosa = 3
'一定期間・・・・バックアップ方法 ChkMode = "1" の場合の期間
' targetdate1 期間開始日「2009/1/1」と指定した場合、2009/1/1 00:00:01以降のファイルが対象
' targetdate2 期間終了日「2009/1/1」と指定した場合、2009/1/1 00:00:00以前のファイルが対象
' ※両方必ず指定
targetdate1 = "1900/01/01"
targetdate2 = "2009/05/31"
'------------
'ログ
'バックアップ処理のログを出力します。
'0・・・・出力なし 1・・・・・出力あり
logmode = "1"
'出力先フォルダ
logfolder = "c:\temp"
'ファイル名
logfilename = "bulog.txt"
'------------
'メッセージ出力モード
' バッチファイルを使用して画面から進捗が確認できます。
'0・・・・出力なし 1・・・・・出力あり
MsgOutMode = "1"
'バッチファイルは下記のようなバッチファイルとしてください。
'バッチファイル例
'----ここから---
'Cscript C:\temp\FileBackup.vbs
'pause
'----ここまで---
'--------------------------------------------
' ここまで↑
'--------------------------------------------
'--メイン開始------------------------------------------
Call writelog("==============================")
Call writelog(" ")
Call writelog(" ファイルバックアップ処理開始!!")
Call writelog(" 2009.4 by kan.massa@gmail.com")
Call writelog(" ")
Call writelog(" チェックモード:" & ChkMode )
Set MsgOut = WScript.StdOut
Call BackupMsg("S") '開始メッセージ出力
'バックアップ先のファイル情報のディクショリナリ化
If ChkMode = "3" Then
cntdicfiles = 0
Set objdic2 =CreateObject("Scripting.Dictionary")
Set objdic3 =CreateObject("Scripting.Dictionary")
Call AddDic(backupsakifoldername)
Call CreateDic(backupsakifoldername)
End If
n=0
cntfiles = 0
foldercnt = 1
Call BackUpFile(backupfoldername)
Call GetFolder(backupfoldername)
Call BackupMsg("E") '終了メッセージ出力
Call writelog(" ")
Call writelog(" 処理数:" & n)
Call writelog(" 対象数:" & cntfiles)
Call writelog(" 対象フォルダ数:" & foldercnt)
Call writelog(" ファイルバックアップ処理終了")
Call writelog(" ")
Call writelog("==============================")
'--メイン終了------------------------------------------
'--関数:フォルダを列挙しバックアップする------------------
'(再帰呼び出し)
Function GetFolder(strTargetPath)
Dim fso,f,fc
Set fso =CreateObject("Scripting.FileSystemObject")
Set f=fso.getfolder((strTargetPath))
for each fc in f.subfolders
Call BackUpFile(strTargetPath & "\" & fc.name)
foldercnt = foldercnt + 1
Call GetFolder(strTargetPath & "\" & fc.name)
next
Set f=nothing
Set fso =nothing
End Function
'--関数:終了------------------------------------------
'--関数:ファイルバックアップ--------------------------
Function BackUpFile(strTargetPath)
Dim fso,f,fc,f2,fckey
Dim copyflg '0・・・コピーしない。1・・・コピー。
'Call writelog(strTargetPath)
Set fso =CreateObject("Scripting.FileSystemObject")
Set f=fso.getfolder(strTargetPath)
writelog(" − 対象フォルダ " &strTargetPath)
for each fc in f.Files
copyflg = 0
targetfolder=replace(strTargetPath,backupfoldername,backupsakifoldername)
'モードにより処理を変える。
Select Case ChkMode
'強制的にある日付以降のものはコピーするモード
Case "1"
'ファイルの作成日時が前回バックアップより新しいかチェックする。
IF fc.datelastmodified > Cdate(targetdate1) and fc.datelastmodified < Cdate(targetdate2) Then
'新しい場合、ファイルをコピーする。
copyflg = 1
End If
'コピー先に最新のファイルがあるかチェックするモード
Case "2"
'ファイルの存在チェックを行う
If fso.FileExists(targetfolder & "\" & fc.name)=True Then
'存在する場合、コピー元が新しいかをチェックする。
Set f2 =fso.GetFile(targetfolder & "\" & fc.name)
If CompFiles(fc.size,f2.size,fc.datelastmodified,f2.datelastmodified) = 1 Then
copyflg = 1
End If
Set f2 =nothing
'コピー先に存在しないのだからコピー
Else
copyflg = 1
End IF
'ディレクトリ構造が違う場合もあるか判定しコピーしてしまうモード
Case "3"
'ファイル名が共通なのがあるか?
fckey = fc.name & fc.size & chgdate(fc.datelastmodified)
IF objdic2.Exists(fckey) = True Then
If CompFiles(fc.size,objdic2.item(fckey),fc.datelastmodified,objdic3.item(fckey))=1 Then
copyflg = 1
End If
'コピー先に存在しないのだからコピー
Else
copyflg = 1
End If
End Select
'コピー判定ONのためコピー処理をする。
If copyflg = 1 Then
writelog(" " & fc.name & " : " & fc.datelastmodified)
'バックアップ処理が必要な場合の処理
If BackupMode = "1" and ChkMode <>"1" Then
If fso.FileExists(targetfolder & "\" & fc.name)=True Then
'存在する場合、コピー元が新しいかをチェックする。
Set f2 =fso.GetFile(targetfolder & "\" & fc.name)
writelog(" backup file " & f2.name & " : " & f2.datelastmodified)
fso.copyfile targetfolder & "\" & f2.name ,targetfolder & "\" & fso.GetBasename(f2.name) & "_" & chgdate(f2.datelastmodified) & "." & fso.GetExtensionName(f2.name),true
Set f2 = nothing
End If
End If
'コピー先ディレクトリがあるかチェックする。
Call CreateFolder(targetfolder)
fso.copyfile strTargetPath & "\" & fc.name,targetfolder & "\" & fc.name ,true
n = n+1
End If
cntfiles = cntfiles + 1
If (cntfiles Mod 1000) = 0 Then
Call BackupMsg("M") 'メッセージ出力
End If
next
Set f= nothing
Set fso = nothing
End Function
'--関数:終了------------------------------------------
'--関数:フォルダ作成----------------------------------
Function CreateFolder(strTargetPath)
Dim fso,t1,st
If left(strTargetPath,1)="\" Then
st=3
st=instr(st,strTargetPath,"\") + 1
Else
st=4
End If
Set fso =CreateObject("Scripting.FileSystemObject")
Do
t1=instr(st,strTargetPath,"\")
If t1=0 Then
If not fso.FolderExists(strTargetPath) Then
Call writelog(" −− フォルダ作成: " & strTargetPath)
fso.CreateFolder strTargetPath
End If
Exit Do
Else
If not fso.FolderExists(mid(strTargetPath,1,t1)) Then
Call writelog(" −− フォルダ作成: " & mid(strTargetPath,1,t1))
fso.CreateFolder mid(strTargetPath,1,t1)
End If
End If
st=t1+1
loop
Set fso =nothing
End Function
'--関数:終了------------------------------------------
'--関数:ファイル情報を取得1--------------------------
'コピー先のディレクトリの取得
Function CreateDic(strTargetPath)
Dim fso,fc
Set fso =CreateObject("Scripting.FileSystemObject")
IF fso.FolderExists(strTargetPath) = False Then
Exit Function
End If
Set f=fso.getfolder((strTargetPath))
for each fc in f.subfolders
Call AddDic(strTargetPath & "\" & fc.name)
Call CreateDic(strTargetPath & "\" & fc.name)
next
Set f=nothing
Set fso =nothing
End Function
'--関数:終了------------------------------------------
'--関数:ファイルバック情報取得2----------------------
'コピー先のファイル情報をディクショナリに入れる。
Function AddDic(strTargetPath)
Dim fso,f,fc,fckey
Dim addflg,cntdicfiles
Set fso =CreateObject("Scripting.FileSystemObject")
IF fso.FolderExists(strTargetPath) = False Then
Exit Function
End If
cntdicfiles = 0
Set f=fso.getfolder(strTargetPath)
writelog(" − コピー先フォルダ " & strTargetPath)
for each fc in f.Files
addflg = 1
fckey = fc.name & fc.size & chgdate(fc.datelastmodified)
IF objdic2.Exists(fckey) = True Then
If fc.datelastmodified > objdic2.item(fckey) Then
objdic2.Remove(fckey)
objdic3.Remove(fckey)
Else
addflg = 0
End If
End If
IF addflg = 1 Then
objdic2.add fckey,fc.size
objdic3.add fckey,fc.datelastmodified
cntdicfiles = cntdicfiles + 1
If (cntdicfiles Mod 1000) = 0 Then
Call BackupMsg("D") 'メッセージ出力
End If
End If
next
writelog(" ディクショナリファイル数 " & cntdicfiles)
Set f=nothing
Set fso =nothing
End Function
'--関数:終了------------------------------------------
'--関数:ファイル比較-----------------------------------
'ファイルの比較を実施する。Windowsの場合秒単位で誤差が
'出るのでこれに対応する。
Function CompFiles(size1,size2,moddate1,moddate2)
CompFiles = 0
' Call writelog("size1:" & size1 & "size2:" & size2 & "moddate1:" & moddate1 & "moddate2:" & moddate2)
'サイズ相違チェック
If size1<>size2 Then
CompFiles = 1
Exit Function
End If
'ファイル最新チェック
' If CDate(moddate1) > DateAdd("s", gosa ,CDate(moddate2)) Then
' CompFiles = 1
' Exit Function
' End If
'ファイル日付チェック
If CDate(moddate1) < DateAdd("s", - 1 * gosa ,CDate(moddate2)) or CDate(moddate1) > DateAdd("s", gosa ,CDate(moddate2)) Then
CompFiles = 1
Exit Function
End If
End Function
'--関数:終了------------------------------------------
'--関数:ログ出力--------------------------------------
'ログ出力
Function writelog(strlog)
Dim fso,outfile
If logmode <> "1" Then
Exit Function
End If
Set fso =CreateObject("Scripting.FileSystemObject")
Set outfile = fso.Opentextfile(logfolder & "\" & logfilename,8,True)
outfile.Writeline NOW() & " " & strlog
outfile.close()
Set outfile = nothing
Set fso = nothing
End Function
'--関数:終了------------------------------------------
'--関数:メッセージ出力--------------------------------
Function BackupMsg(Mode)
Dim NowDateTime
If MsgOutMode <> "1" Then
Exit Function
End If
On Error Resume Next
NowDateTime = Date & " " & Time & " "
Select Case Mode
Case "S"
MsgOut.WriteLine NowDateTime & "File Backup - Start"
MsgOut.WriteLine NowDateTime & " from " & backupfoldername
MsgOut.WriteLine NowDateTime & " to " & backupsakifoldername
MsgOut.WriteLine NowDateTime & " Check mode :" & ChkMode
Case "D"
MsgOut.WriteLine NowDateTime & "File Copy - Running MakeDictionary:" & cntdicfiles
Case "M"
MsgOut.WriteLine NowDateTime & "File Copy - Running Checkfile:" & cntfiles & " Backup:" & n
Case "E"
MsgOut.WriteLine NowDateTime & "File Copy - End"
MsgOut.WriteLine
MsgOut.WriteLine NowDateTime & "Backup:" & n & " all files:" & cntfiles & " all Directory :" & foldercnt
End Select
End Function
'--関数:終了------------------------------------------
'--関数:日付変換--------------------------------------
Function chgdate(ddate)
Dim tempdate
If Isdate(ddate)=False Then
chgdate = ""
Exit Function
End If
tempdate = Year(ddate) & right("0" & Month(ddate),2) & right("0" & day(ddate),2)
tempdate = tempdate & right("0" & hour(ddate),2) & right("0" & minute(ddate),2) & right("0" & second(ddate),2)
chgdate = tempdate
End Function
'--関数:終了------------------------------------------
|