OneDrive for Business に robocopy でバックアップ


OneDrive for Business 上の個人領域に、robocopyでバックアップを定期的に作成してみようと試行錯誤した際の備忘録です。


 一般的なOneDrive for Businessは、ローカルPC上の任意のフォルダ/ファイルを自動的にOneDrive for Business側に同期してくれるみたい(今回初めて利用するので、よくわかってないのですが・・・)なので、本来こんな仕組みは要らないんでは、とも思いますが、いまの仕事で利用しているOneDrive for Business(というかWindows10)には、PC側にOneDrive for Business同期アプリ(groove.exe or onedrive .exe )がインストールされていない(入れてもいけない・・・)ので、都度、手作業でアップロードしています。

 OneDrive側にバックアップを保存するときに、毎度GUIでドラッグもなんなので、robocopy で自動化できないかな、と。

実際に試してみたところ、まあ、動作するにはしたのですが、

  • robocopy /MIR が、常にフルコピーになってしまう。(差分コピーしてくれない・・・。でも /purge は機能する)
  • robocopy /Z が使えない(エラーになる)。(OneDrive側の権限の問題、だと思う)
  • robocopy の実行前に、OneDrive for business にログインして「エクスプローラーで表示」をしないと、UNCパスとして扱えない。

の制限があることが判明しました。 とほほ。。
(/MIR が差分してくれない、のはおそらくOneDrive側のタイムスタンプの扱い – ブラウザからアップロードすると、もとのファイルのタイムスタンプが保持されなくて、アップロード時の日時に置き換わる – が影響しているのでは、と仮定したものの、原因が判明しなかったので、OneDrive相手に/MIRはできないものと割り切ることにしました)

/MIR で差分してくれないので、Dailyでフルバックアップ(・・/MIR がうまく動けば、こんなスクリプトにしなくても・・・)することに。
また、robocopyはUNCパスでないと扱えないので、毎度OneDrive側から「エクスプローラーで表示」をするのが必要で、自動化ってなんだっけ、、、なんですが、、

1)robocopy を Powershell スクリプト(.ps1) に記載して実行。
2).ps1 をWindowsのタスクスケジューラーに登録して、定期的に実行。

を実装して自動バックアップをすることにします。



手順ですが、

1) OneDrive for business の UNCパス を確認する。
ブラウザからログインすると、私の場合、下記のようなURL。

【URL】
https://hogehoge.sharepoint.com/personal/Your_Name/_layouts/20/onedrive.aspx

これをUNCパスで表現すると、以下のように。(ネットワークドライブにマウントすると、UNCパスが判明する)

【UNC】
\\hogehoge.sharepoint.com@SSL\DavWWWRoot\personal\Your_Name\Document

2)  OneDrive for business 側にバックアップ受け入れ用のフォルダを作成。
  例) 99.Backup

3)  PC側に .ps1 ファイル(ページ最下段にサンプルコード)を配置。
  例)D:\01.PSScripts\01.BackupToOneDrive.ps1

4) PC側にrobocopy実行時のログファイルを保管するフォルダを作成。
  例)D:\91.Robocopy_Log

5) .ps1 をタスクスケジューラーに登録。
  「ファイルを指定して実行」で「taskschd.msc」を起動して、新しいタスクを作成。
  タスクの「操作」には以下を指定。

【プログラム/スクリプト】
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

【引数の追加】
-ExecutionPolicy RemoteSigned -Windowstyle hidden -File D:\01.PSScripts\01.BackupToOneDrive.ps1

↑ -File で、.ps1 を配置した絶対パスを指定。

そのほか、タスクの「トリガー」や「条件」などは環境に併せて適宜。

スクリプト(.ps1)の中身は以下になります。
(robocopy の実行時に、日時の文字列を含んだバックアップフォルダーとログファイルを作成。 -> バックアップが終了したら、古いフォルダ/ログを削除、する流れです。OneDriveがUNCパスで確認できなかったら、その旨の警告をし、警告/確認に何回か失敗すると終了させるようにしてます)


###
### robocopyでOneDriveにフォルダ/ファイルをコピー
###
### STEP1 : robocopy オプションを変数で指定。
### STEP2 : robocopy の実行。 ターゲットのOneDriveがUNCパスとして認識されていなければ、警告 -> 5回後に終了。
### STEP3 : 古いバックアップフォルダー(OneDrive)とrobocopyのログ(ローカル)を削除。 


###########
###### Step1 : Define robocopy paramerters.
######

### コピー元の指定
$SrcDir = “D:\”
### $SrcDir = $env:USERPROFILE\Desktop

### コピー先の指定
$NowDate = Get-Date -Format “yyyyMMdd_HHmmss”
$OneDrive_Private = “\\hogehoge.sharepoint.com@SSL\DavWWWRoot\personal\Your_Name\Documents\”
$BKFolder = “99.Backup\”
$DstDir = $OneDrive_Private + $BKFolder + $NowDate

### コピー対象【外】のファイル/フォルダを指定
$ExcludeFiles = “desktop.ini”
$ExcludeDir = “`$RECYCLE.BIN”, “System Volume Information”, “91.Robocopy_Log”

### robocopy のログファイル
$LogDir = “D:\91.Robocopy_Log\”
$LogFile = $LogDir + ‘robocopy’ + ‘_’ + $NowDate + ‘.log’

### ファイルコピーに失敗した際のリトライ
$Retry = 2
$RetryWaitTime = 30

######
###### Step1: END
###########


###########
###### Step2 : Execute robocopy.
######

$Stoploop = $false
[int]$Retrycount = “0”
$STEP3 = $false

While ($Stoploop -eq $false) {
	### OneDriveのUNCパスを確認
	switch (Test-Path $OneDrive_Private) {
		### パスが確認できたら、robocopyを実行
		“True” {
			New-Item -ItemType Directory -Path $DstDir
			robocopy $SrcDir $DstDir /E /R:$Retry /W:$RetryWaitTime /XF $ExcludeFiles /XD $ExcludeDir /LOG:$LogFile /NP /Z
			$Stoploop = $true
			$STEP3 = $true
		}
		### UNCパスが確認できない場合、警告のポップアップを表示
		“False” {
			if ($Retrycount -gt 4) {
				### MessageBox の表示
				### MessageBox クラスを含む.NET Frameworkライブラリをロード(毎回は不要?)
				Add-Type -Assembly System.Windows.Forms
				$MBTitle = “(失敗)OneDriveへの自動バックアップ”
				$MBText1 = “OneDriveへの接続が確認できませんでした。”
				$MBText2 = “リトライに5回失敗したため、自動バックアップ処理を終了します。”
				$MBText3 = “(再度実行したい場合は、OS再起動をしてください)”
				[System.Windows.Forms.MessageBox]::Show(“$MBText1`n$MBText2`n$MBText3”, $MBTitle)
				Start-Sleep -Seconds 900 ### 900sec = 15min
				$Stoploop = $true
			}
			else {
				$Retrycount = $Retrycount + 1
				### MessageBox の表示
				### MessageBox クラスを含む.NET Frameworkライブラリをロード(毎回は不要?)
				Add-Type -Assembly System.Windows.Forms
				$MBTitle = “(失敗)OneDriveへの自動バックアップ”
				$MBText1 = “OneDriveへの接続が確認できませんでした。”
				$MBText2 = “自動バックアップをするには、OneDriveにログインして、「エクスプローラーで表示」を実行してください。”
				$MBText3 = ” はい : 15分後に再試行します。”
				$MBText4 = ” いいえ : 処理を停止します。”
				$MBInput = [System.Windows.Forms.MessageBox]::Show(“$MBText1`n$MBText2`n$MBText3`n$MBText4”, $MBTitle , “YesNo”)

				switch ($MBInput) {
						‘Yes’ {
						Start-Sleep -Seconds 900 ### 15分
						}
						‘No’ {
						$Stoploop = $true
						}
					}
				}
		}
	}
}

######
###### Step2 : END
###########


###########
###### Step3 : Delete an old robocopy-Logs, and BackUped Items on OneDrive.
######

$DeleteTime = “-14400”
### $DeleteTime = “-n”; n is minutes.
### 10日 = 14400 (= 60min * 24hour * 10days)

if ($STEP3 -eq $true) {
	Get-ChildItem $LogDir |
	Where-Object {
	$_.CreationTime -lt (Get-Date).AddMinutes($DeleteTime)
	} |
	foreach {
	Remove-Item -Recurse -Force $_.FullName
	}

	Get-ChildItem -Force -Path ($OneDrive_Private + $BKFolder) |
	Where-Object {
	$_.CreationTime -lt (Get-Date).AddMinutes($DeleteTime)
	} |
	foreach {
	Remove-Item -Recurse -Force $_.FullName
	}
	}
else {
exit
}

######
###### Step3 : END
###########

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です