web-dev-qa-db-ja.com

powershellに含まれるrobocopyサマリー情報を取得する方法?

サーバー間でファイルの違いを比較し、変更をミラーリングするかどうかを確認する簡単なスクリプトを作成しました。変更がない場合は、コピーのプロンプトをインテリジェントに表示しないでください。

スクリプト:

robocopy "$cSource" "$cDestination" /E /L /FP

$cDecision = Read-Host "Continue = 1, anything else = Stop"

if ($cDecision -eq "1") {
robocopy "$cSource" "$cDestination" /MIR /FFT /Z /W:5 /MT:64 /XX /log:$cLogLocation

Invoke-item $cLogLocation

}

else { Write-Host "Quit!" }

RobocopyがMismatch、Failed、Extras、およびCopiedについて0を報告した場合、Powershellが続行を要求しないようにしたいと思います。この特定のプロジェクトではそれほど重要ではありませんが、そのようなチェックのいくつかの便利な使用法を考えることができます。ありがとう!

7
jski

ついに10秒で答えなかったもの!私はあなたの問題を使用して、Powershellについてさらに学習し続けました。以下は私にとってはうまくいきます、他の人がこのコードをどのようにスリム化するか見てみたいです:

Clear-Host
$ErrorActionPreference = "Continue"
$DebugPreference = "Continue"
$VerbosePreference = "Continue"

@"

## robocopy_helper.ps1 ########################################################
Usage:        powershell -ExecutionPolicy Bypass -File ./robocopy_helper.ps1

Purpose:      Dry run before Full run of robocopy

History:      07/11/2014  -  Created
###############################################################################

"@

## User Supplied Variables
$cSrc = "C:\Temp"
$cDst = "C:\Temp2"
$cLog = "c:\robo.log"

## Robocopy Dry Run
$robo_test = robocopy "$cSrc" "$cDst" /E /L /FP

## Use Regular Expression to grab the following Table
#               Total    Copied   Skipped  Mismatch    FAILED    Extras
#    Dirs :         1         0         1         0         0         0
#   Files :         1         0         1         0         0         0
$robo_results = $robo_test -match '^(?= *?\b(Total|Dirs|Files)\b)((?!    Files).)*$'

## Convert Table above into an array
$robo_arr = @()
foreach ($line in $robo_results){
    $robo_arr += $line
}

## Create Powershell object to tally Robocopy results
$row = "" |select COPIED, MISMATCH, FAILED, EXTRAS
$row.COPIED = [int](($robo_arr[1] -split "\s+")[4]) + [int](($robo_arr[2] -split "\s+")[4])
$row.MISMATCH = [int](($robo_arr[1] -split "\s+")[6]) + [int](($robo_arr[2] -split "\s+")[6])
$row.FAILED = [int](($robo_arr[1] -split "\s+")[7]) + [int](($robo_arr[2] -split "\s+")[7])
$row.EXTRAS = [int](($robo_arr[1] -split "\s+")[8]) + [int](($robo_arr[2] -split "\s+")[8])

## If there are differences, lets kick off robocopy again
if ( ($row.COPIED + $row.MISMATCH + $row.FAILED + $row.EXTRAS) -gt 0 ){
    robocopy "$cSrc" "$cDst" /MIR /FFT /Z /W:5 /MT:64 /XX /log:$cLog
    Invoke-item $cLog
}
else { Write-Host "Folders '$cSrc' and '$cDst' are twins" }

注:上記の正規表現をピリオドからアスタリスクの直前のスペースに変更しました。これにより、ファイル名/パス内の「ファイル」、「ディレクトリ」、または「合計」をキャッチするリスクがなくなります。元の行は後世のために下にあります。
jski 2014/07/16

$ robo_results = $ robo_test -match '^(?= .?\ b(Total | Dirs | Files)\ b)((?! Files)。) $'

6
Lars

これは古いスレッドであることを理解していますが、robocopyによって返される終了コードを使用して変更が存在するかどうかを判断することもできます(値0は変更がないことを示します)。これを行うには2つの方法があります。

  1. 上記のrobocopyステートメントを実行し、次の行で$ LastExitCodeの値を確認します。
  2. Start-Processを使用します。
 $ RobocopyResult = Start-Process -FilePath robocopy -ArgumentList $ RobocopyParams -Wait -PassThru 
 $ RobocopyResult.ExitCode 

Start-Processを使用する場合、-PassThruを使用することが重要です。それ以外の場合、$ RobocopyResultに値は設定されません。

他の終了コードは http://ss64.com/nt/robocopy-exit.html にリストされています。

2
Aakash Shah

これが私のハックです。私のコードはログファイルを読み取り、集計フィールドに一致する行を探します。次に、ファイルとディレクトリの統計情報を含む2つのオブジェクトに解析します。

        ### Read data from log summary at end of RoboCopy log
        $Props = ((cat $RoboCopyLogFile | ? {$_ -like "*Total*Copied*Skipped*Mismatch*FAILED*Extras*"}) | select -Last 1).split(" ") | ? {$_ -match "a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z"}
        $Dirs = (((cat $RoboCopyLogFile | ? {$_ -like "*Dirs : *"})) | select -Last 1).split(" ") | ? {$_ -match "1|2|3|4|5|6|7|8|9|0"}
        $Files = (((cat $RoboCopyLogFile | ? {$_ -like "*Files : *"})) | select -Last 1).split(" ") | ? {$_ -match "1|2|3|4|5|6|7|8|9|0"}
        ### Loop through the propteries of the summary
        $i = 0
        $FileStats = @{}
        $DirStats = @{}
        foreach($Prop in $Props)
        {
            $FileStats.("$Prop") = $Files[$i]
            $DirStats.("$Prop") = $Dirs[$i]
            $i++
        }
        $FileStats = New-Object -TypeName psobject -Property $FileStats
        $DirStats = New-Object -TypeName psobject -Property $DirStats
0
Jason