ファイルバックアップスクリプト

2009/5/18


ファイルバックアップスクリプトできました。
ベクターからダウンロードできます。

ダウンロードはこちらから・・・・http://www.vector.co.jp/soft/winnt/util/se475750.html

あっ!スクリプトなんで、勝手にいぢってくださいね♪

■ ソフトの説明 
WSHを使用したファイルバックアップのスクリプトになります。
PC内、サーバ→NAS、NAS→PC、PC→PC間のコピーのユーティリティです。
全ファイルコピーだと時間がかかります。デジカメの写真の
バックアップも大変ですよね。全部だと・・・・。
ってことで
・ある一定期間に更新があったものを全部コピー
・同名ファイルがある場合はファイル(更新日時、サイズ)比較
を実施して違う場合はコピー
(ディレクトリ一致&ファイル一致)
というソフト(スクリプト)を作ってみました。
そのままでは芸が無いので・・・
・タスクスケジューラに仕掛けて動作させる事(画面なし)
・バッチファイルより起動し進捗がわかるもの
・同名ファイルの場合コピー先のファイルをリネーム
を用意しました。
またバックアップが取れているか不安になる方のために
・ログファイル出力
があります。
自宅では、デジカメの写真を内蔵HDDから外付けHDDに差分だけコピーしています。



======
って事でここにはソースを貼ってしまいます。
WSHのお勉強にどうぞ!!


	

'==========================================================
'
'            ファイルバックアップスクリプト
'		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
'--関数:終了------------------------------------------


=====================================================================
【ソ フ ト名】 ファイルバックアップスクリプト
【バージョン】 第1.1版
【ソフト種別】 フリーウェア
【動作可能OS】 Windows XP,Vista等
【公開開始日】 2009/05/02
【配布File 】 FileBackup.vbs,filebackup.bat,はじめに読んでね.txt
【著 作 権】 Copyright(C) kan2525
【開発環境 】 Windows Vista,Xp
【連 絡 先】 http://minkara.carview.co.jp/userid/125065/profile/
               kan.massa@gmail.com
=====================================================================
■【ソフト紹介】


■【インストール方法】

(1)手動起動で使用する。(画面表示あり)

解凍後
・filebackup.batをデスクトップ等に配置する。
・FileBackup.vbsの各種設定を変更する。

(2)自動起動でバッチで処理する。(画面表示なし)

解凍後
・FileBackup.vbsの各種設定を変更する。
・タスクスケジューラにFileBackup.vbsを登録する。

■【アンインストール方法】

・filebackup.bat,FileBackup.vbsを削除してください。

■【設定方法】

−バックアップの設定
FileBackup.vbsにバックアップ元、バックアップ先等を指定します。
・filebackup.batをメモ帳で開きます。

'--------------------------------------------
'	ユーザーセッティングエリア
'	ここから変更可能↓
'--------------------------------------------
〜
'--------------------------------------------
'	ここまで↑
'--------------------------------------------
の内容を変更してください。

・フォルダの指定
・バックアップ方法の指定
・コピー先にファイルが存在する場合の処理方法の指定
・ログの設定
・進捗表示の設定

があります。

−FileBackup.vbsをc:\temp以外に配置した場合)
・filebackup.batをメモ帳で開きます。
・Cscript C:\temp\FileBackup.vbsをFileBackup.vbsを配置した場所を
 指定します。

■【参考】

・スクリプトはどこに配置しても構いません。ログを出力するフォルダ
とバッチファイルからのリンクを修正してあげてください。

・コピーできたか不安な方は、コピー終了後コピー前後のフォルダの
プロパティを見て、使用済み容量とファイル数を比較してください。

■【その他】

・この配布ファイルはウィルスソフトによりチェックしてありますが、
 検索できなかったウィルスがあった場合には、
 いかなる損害が発生したとしても、作者は一切責任を負いません。

・このソフトはフリーソフトウェアですが無断で転載・再配布することを禁止
します。
・不具合などがありましたらメールにて 連絡いただけたら幸いです。

・スクリプトはご自由に修正して頂いた構いませんしコピーして使って頂いて
構いません。でも著作権は放棄していないので2次製品になって公開の場合は
メールにてご連絡ください&下記クレジットをお願いいたします。

---ここから
参考:
Copyright(C) kan2525
FileBackup.vbs
http://minkara.carview.co.jp/userid/125065/profile/
kan.massa@gmail.com
---ここまで

・フォルダの中身の差分を抽出するツールを作成中です。

■【免責事項】
このソフトを使用して起こるいかなるトラブルも責任を負いかねます。
自己責任で使用してください。
2009/04/08  V1.0 beta release
2009/05/02    V1.0 release
2009/05/19    V1.1 release
		バックアップファイルが作成されるモードの記述に誤り
			誤 ' ・ChkMode = "1","3"でのみ有効
			正  ' ・ChkMode = "2","3"でのみ有効
		バックアップファイルを作成する方法の表現が不親切
			追記
			'0・・・バックアップしない。
			'1・・・バックアップする。


↑戻る