◇§ 概要 ◇
スキップされたファイルを含むログから、スキップされたファイルを含まないログを引くことで、スキップされたファイル群を炙り出すことを目指したコードです。このコードではスキップされたフォルダは無視されます。また、フォルダにファイルリストの作成許可がない場合はエラーが記録されます。(取得可:ファイル・シンボリックリンク・ハードリンク・ジャンクション等)
◇§ 通常コピー用(接合ポイント除外)◇
# 準備
PowerShell
#〈文字コードを UTF-8 に変更〉
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
#〈コピー元のディレクトリ〉
$src = "<source directory>"
#〈コピー先のディレクトリ〉
$dest = "<destination directory>"
#〈ログの保存先〉
$Temp = [Environment]::GetEnvironmentVariable('Temp', 'Machine').TrimEnd("\")
$diff_3 = "${Temp}\diff_3.rc.log"
$diff_4 = "${Temp}\diff_4.rc.log"
#〈変数の確認〉
$src,$dest,$diff_3,$diff_4
#〈ログファイルの作成〉
[void](New-Item -Path $diff_3, $diff_4 -Force -Type File -Value "`r`n")
# ドライランもどき
PowerShell
#〈スキップされたファイルをログに記録する〉
robocopy "$src" "$dest" /L /E /COPY:DAT /DCOPY:DAT /IT /IM /XO /XJ /R:0 /W:0 /TS /FP /NP /NS /NC /NJH /UNILOG:nul /TEE /NJS /V | Tee-Object -Variable diff_1
#〈スキップされたファイルをログに記録しない〉
robocopy "$src" "$dest" /L /E /COPY:DAT /DCOPY:DAT /IT /IM /XO /XJ /R:0 /W:0 /TS /FP /NP /NS /NC /NJH /UNILOG:nul /TEE | Tee-Object -Variable diff_2
#〈diff で比較〉
Compare-Object -Refere:$diff_2 -Differe:$diff_1 | Select-Object -Property InputObject | ForEach-Object -Begin {
""; ""
"Skipped or Extras(destfile etc.)"
"--------------------------------"
$Pattern = "^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} ERROR"
$SkipReason = $false
$ExecFlag = $true
$Summary = @()
$i = 0
} -Process {
$Line = $_.InputObject
if ($SkipReason) {
$SkipReason = $false
} elseif ([String]::IsNullOrWhiteSpace($Line)) {
} elseif ($Line -match $Pattern) {
$SkipReason = $true
} elseif ($Line -match "^-----+$") {
$ExecFlag = $false
} elseif ($ExecFlag) {
Write-Output $Line.Trim()
} else {
$Summary += $_ | Select-Object @{Name="Summary"; Expression={$_.InputObject}}
}
} -End {
""; ""
"Failed"
"------"
$ErrorLines = @()
$ErrorLines += $diff_2 | Select-String -Pattern $Pattern
$ErrorLines.Line; ""
$Summary
}
# 実際に実行
PowerShell
#〈ドライランもどきを使ってスキップされたファイルをログに記録する〉
robocopy "$src" "$dest" /L /E /COPY:DAT /DCOPY:DAT /IT /IM /XO /XJ /XF "$diff_3" /R:0 /W:0 /TS /FP /NP /NS /NC /NJH /UNILOG:nul /TEE /NJS /V | Add-Content $diff_3 -Enc:UTF8 -Pass
#〈実際のコピー(スキップされたファイルをログに記録しない)〉
robocopy "$src" "$dest" /E /COPY:DAT /DCOPY:DAT /IT /IM /XO /XJ /XF "$diff_4" /R:0 /W:0 /TS /FP /NP /NS /NC /NJH /UNILOG:nul /TEE | Add-Content $diff_4 -Enc:UTF8 -Pass
#〈diff で比較〉
Compare-Object -Refere(GC $diff_4 -Enc:UTF8) -Differe(GC $diff_3 -Enc:UTF8) | Select-Object -Property InputObject | ForEach-Object -Begin {
$Pattern = "^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} ERROR"
$SkippedOrExtras = @()
$SkipReason = $false
$ExecFlag = $true
$ErrorLines = @()
$Summary = @()
$i = 0
} -Process {
$Line = $_.InputObject
if ($SkipReason) {
$SkipReason = $false
# $ErrorLines += $Line
} elseif ([String]::IsNullOrWhiteSpace($Line)) {
} elseif ($Line -match $Pattern) {
$SkipReason = $true
$ErrorLines += $Line
} elseif ($Line -match "^-----+$") {
$ExecFlag = $false
} elseif ($ExecFlag) {
$SkippedOrExtras += $Line.Trim()
} else {
$Summary += $_ | Select-Object @{Name="Summary"; Expression={$_.InputObject}}
}
} -End {
""; ""
"Skipped or Extras(destfile etc.)"
"--------------------------------"
$SkippedOrExtras
""; ""
"Failed"
"------"
$ErrorLines
"";
$Summary
}
# 後処理
PowerShell
Remove-Item $diff_3, $diff_4
# attrib /d -s -h "$dest" # 管理者
◇§ オプション紹介 ◇
注意
除外オプション/X~
を付けると diff
での出力に除外対象Extras
が追加されます。
- つけておいたほうが良いオプション:
/B
(管理者権限必須)/J
(単一のファイルサイズが SSD のキャッシュより大きい場合)/XJ
/XX
(/MIR
or /PURGE
を使う場合)/R:0
/W:0
/NP
(ログをファイルに出力する場合)[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
+ /UNILOG:nul /TEE
-
※英語句は引数から予想した非略語
- 基本オプション:
- コピー対象をリストアップするのみ。ドライランに近い。ログには出力する。エラーの内容は表示しない。
- SeBackupPrivilege・SeRestorePrivilege を付与
- サブディレクトリをコピー(空のディレクトリは含まない)
- 空のディレクトリを含むサブディレクトリをコピー
- I/Oバッファリングを解除(/CREATE時にはいらない)
- ディレクトリツリーと0サイズのファイルを作成
- コピーオプション:
- D=データ、A=属性、T=タイムスタンプ
S=セキュリティ(NTFS ACL)、O=所有者情報、U=監査情報
E=拡張属性、X=代替データストリームをスキップ
指定したものをコピーに含める - ファイル属性のみの変更を含む
- 変更日時が異なる場合を含む(新旧問わない)
/IMについて1
/IMについて2 - 同じファイル(名前、サイズ、時刻、すべての属性が同じ)を含める
- ジャンクション配下のファイルやフォルダを追跡コピーするのではなく、ジャンクション自体を作成
- シンボリックリンクのリンク先の対象をコピーするのではなく、シンボリックリンクを作成
- 除外オプション:
- src:Old、dest:New の場合は上書きしない
- ファイルとディレクトリのシンボリックリンクと接合ポイントを除外
- コピー先(dest)にだけ存在するファイルとディレクトリを削除しない
- 再試行オプション:
- 失敗したコピーに対する再試行数(既定値は 1,000,000)
- 再試行と再試行の間の待機時間(既定値は 30 秒)
- ログオプション:
- 表示:
- CLI 出力にスキップされたファイルを含める(ディレクトリは含まれない・ジャンクションは含まれる)
- コピー元(src)ファイルのタイムスタンプを表示する
- ファイルの完全なパスを表示する
- UTF-8 に対応させる(nul = /dev/null)
参考1
参考2 - ファイルに出力する場合でも CLI にも表示する
- 除外:
- コピーの完了率を表示しない
- ファイルサイズを出力しない
- ファイルクラスを出力しない
- 日時と引数の出力を抑制する
- 統計情報(結果の概要)非表示
/L
ListOnly
/B
BackupMode
/S
SubDirectory
/E
Empty | SubDirectory
/J
Jumbo
/CREATE
/COPY:DATSOUX
Date・Attributes・Time Stamp・Security・Owner・aUditing・eXtra
/DCOPY:DATEX
Date・Attributes・Time Stamp・Extended・eXtra
/IT
Includes Tweaked
/IM
Includes Modified
/IS
Includes Same
/SJ
SoftLinks (Junctions)
/SL
Symbolic Links
/XO
eXcludes Older
/XJ
eXcludes Junction
/XX
eXcludes eXtra
/R:0
Retries
/W:0
WaitTime
/V
Verbose
/TS
Time Stamp
/FP
Full Path
/UNILOG:nul
Unicode Log > Null
/TEE
T
/NP
No Progress
/NS
No Size
/NC
No Class
/NJH
No Job Header
/NJS
No Job Summary