0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Robocopy でスキップされたファイルを判別するための補助コード

Last updated at Posted at 2024-12-05

◇§ 概要 ◇

 スキップされたファイルを含むログから、スキップされたファイルを含まないログを引くことで、スキップされたファイル群を炙り出すことを目指したコードです。このコードではスキップされたフォルダは無視されます。また、フォルダにファイルリストの作成許可がない場合はエラーが記録されます。(取得可:ファイル・シンボリックリンク・ハードリンク・ジャンクション等)

◇§ 通常コピー用(接合ポイント除外)◇

# 準備

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
 ※英語句は引数から予想した非略語
基本オプション:
/L ListOnly
コピー対象をリストアップするのみ。ドライランに近い。ログには出力する。エラーの内容は表示しない。
/B BackupMode
SeBackupPrivilege・SeRestorePrivilege を付与
/S SubDirectory
サブディレクトリをコピー(空のディレクトリは含まない)
/E Empty | SubDirectory
空のディレクトリを含むサブディレクトリをコピー
/J Jumbo
I/Oバッファリングを解除(/CREATE時にはいらない)
/CREATE
ディレクトリツリーと0サイズのファイルを作成
コピーオプション:
/COPY:DATSOUX Date・Attributes・Time Stamp・Security・Owner・aUditing・eXtra
/DCOPY:DATEX Date・Attributes・Time Stamp・Extended・eXtra
 D=データ、A=属性、T=タイムスタンプ
 S=セキュリティ(NTFS ACL)、O=所有者情報、U=監査情報
 E=拡張属性、X=代替データストリームをスキップ
指定したものをコピーに含める
/IT Includes Tweaked
ファイル属性のみの変更を含む
/IM Includes Modified
変更日時が異なる場合を含む(新旧問わない)
/IMについて1
/IMについて2
/IS Includes Same
同じファイル(名前、サイズ、時刻、すべての属性が同じ)を含める
/SJ SoftLinks (Junctions)
ジャンクション配下のファイルやフォルダを追跡コピーするのではなく、ジャンクション自体を作成
/SL Symbolic Links
シンボリックリンクのリンク先の対象をコピーするのではなく、シンボリックリンクを作成
除外オプション:
/XO eXcludes Older
src:Old、dest:New の場合は上書きしない
/XJ eXcludes Junction
ファイルとディレクトリのシンボリックリンクと接合ポイントを除外
/XX eXcludes eXtra
コピー先(dest)にだけ存在するファイルとディレクトリを削除しない
再試行オプション:
/R:0 Retries
失敗したコピーに対する再試行数(既定値は 1,000,000)
/W:0 WaitTime
再試行と再試行の間の待機時間(既定値は 30 秒)
ログオプション:
 表示:
/V Verbose
CLI 出力にスキップされたファイルを含める(ディレクトリは含まれない・ジャンクションは含まれる)
/TS Time Stamp
コピー元(src)ファイルのタイムスタンプを表示する
/FP Full Path
ファイルの完全なパスを表示する
/UNILOG:nul Unicode Log > Null
UTF-8 に対応させる(nul = /dev/null)
参考1
参考2
/TEE T
ファイルに出力する場合でも CLI にも表示する
 除外:
/NP No Progress
コピーの完了率を表示しない
/NS No Size
ファイルサイズを出力しない
/NC No Class
ファイルクラスを出力しない
/NJH No Job Header
日時と引数の出力を抑制する
/NJS No Job Summary
統計情報(結果の概要)非表示
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?