PowerShellで7-zip.exeを使って指定ファイルを自動バックアップするスクリプト

もちろん、別途powershellを定期的に自動実行する仕組みは必要。自分の記事だけど参照。
[PowerShellで重いタスクスケジューラーに頼らずcronを実行・管理する方法 - Qiita](http://qiita.com/Fushihara/items/d49f674f5e1d64646315)
[「windows」で「PowerShell」を「一切画面表示せず」に「タスクスケジューラに登録」する方法を再確認 - Qiita](http://qiita.com/Fushihara/items/1576f08825f39706174f)

そしてこんな感じでアーカイブするファイルを定義する

```ps1
doArchive "JaneLast.dat" {
	# Join-Path
	# Get-Date -Format "yyyy年MM月dd日(ddd)HH時mm分ss秒"
	# New-item -type directory
	$baseDir = $args[0]
	$subDir = Join-Path $baseDir (Get-Date -Format "yyyy年MM月dd日")
	New-item $subDir -type directory
	copy-item "C:\OpenJane\last.dat" $subDir
	copy-item "C:\OpenJane\last.bak" $subDir
}

```

この例だと、JaneLast.dat.zip の中に2016年10月12日 というディレクトリを作って、その中にlast.datとlast.bakを保存する
運用を続けると、JaneLast.dat.zipの中には一日ごとのファイルが保存され続ける。
具体的な処理はdoArchive メソッドの第二引数ので自由に制御出来る。
この第二メソッドは、引数にtempディレクトリに作られたカラのフォルダのパスが渡されるので、そのフォルダの中にバックアップしたいファイルを手動でコピーしてメソッドを抜ける。
後は、メイン関数がそのフォルダの中をまるごとzipして、ファイルが無ければ新規作成 あれば追記する。tempのディレクトリをまるごと消して終了

フォルダ名を工夫すれば一日ごとじゃなくて一ヶ月ごとも出来るし、曜日にすれば一週間のローテートが出来る。

ログファイルはこんな感じ。アーカイブ名と、ファイルサイズと、ファイルサイズの増加量。

```text
2016/05/18(水)23:19:07 JaneLast.dat 31.732 Mbyte +957 byte
```



以下コード。煮るなり焼くなり好きにどうぞ

```ps1
$7zip="C:\7-Zip\7z.exe" # 書き換えてね
$logPath="${PSScriptRoot}\log.txt"
$archivePathDir="${PSScriptRoot}\archives\"

function doArchive([string]$zipName,$callback){
	$start = get-date
	$error = ""
	$tempDir = $env:temp + "\archive-" + (Get-Random)
	[String]$callbackLog = ""
	[String]$zipLog = ""
	[long]$beforeSize = 0
	[long]$afterZipSize = 0
	try{
		$zipPath ="${archivePathDir}${zipName}.zip"
		if ( Test-Path $zipPath ){
			$beforeSize = (get-childItem "${zipPath}").length
		}
		$callbackLog = & $callBack $tempDir
		$zipLog = & "$7zip" a "${zipPath}" "${tempDir}/*"
		Remove-Item -LiteralPath "${tempDir}" -Force -Recurse
		$afterZipSize = (get-childItem "${zipPath}").length
	}catch{
		$error = $_
	}
	$end = get-date
	# ログ書き出し
	# 2016/01/01(日)00:00:00 janelast.dat 圧縮したファイル
	$logText =$start.toString("yyyy/MM/dd(ddd)HH:mm:ss")+" "+$zipName + " "
	if( $error -ne "" ){
		$logText+="★ ${error}"
	}
	$logText += ( formatSize $afterZipSize )
	if ( $afterZipSize -gt $beforeSize ){
		$logText += " +" +( formatSize ($afterZipSize-$beforeSize) )
	}else{
		$logText += " -" +( formatSize ($beforeSize-$afterZipSize) )
	}
	$logText >> $logPath
}
function formatSize([double]$size){
	# 引数のバイトを  10.212 Kbyte の様にフォーマットして表示する
	$digit = 1000
	if ( $size -lt $digit ){
		"${size} byte"
	}elseif( $size -lt $digit*$digit ){
		"{0:0.000} Kbyte" -F ( $size / $digit )
	}elseif( $size -lt $digit*$digit*$digit ){
		"{0:0.000} Mbyte" -F ( $size / $digit / $digit )
	}elseif( $size -lt $digit*$digit*$digit*$digit ){
		"{0:0.000} Gbyte" -F ( $size / $digit / $digit / $digit )
	}elseif( $size -lt $digit*$digit*$digit*$digit*$digit ){
		"{0:0.000} Tbyte" -F ( $size / $digit / $digit / $digit / $digit )
	}else{
		"${size} byte"
	}
}
# ここからアーカイブ情報
doArchive "JaneLast.dat" {
	# Join-Path
	# Get-Date -Format "yyyy年MM月dd日(ddd)HH時mm分ss秒"
	# New-item -type directory
	$baseDir = $args[0]
	$subDir = Join-Path $baseDir (Get-Date -Format "yyyy年MM月dd日(ddd)HH時mm分ss秒")
	#$subDir = Join-Path $baseDir (Get-Date -Format "yyyy年MM月dd日")
	New-item $subDir -type directory
	copy-item "C:\OpenJane\last.dat" $subDir
	copy-item "C:\OpenJane\last.bak" $subDir
}

```