Powershell – How to get robocopy summary information involved in powershell

mirrorpowershellrobocopy

I have a quick script written to compare file differences across servers, and then give a prompt for whether to mirror the changes. I'd like it to intelligently NOT prompt for copying if there aren't any changes.

The script:

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!" }

I'd like to have Powershell not ask to continue if Robocopy reports 0 for Mismatch, Failed, Extras, and Copied. It's not very important for this particular project, but I can think of a couple useful uses for such a check. Thanks!

Best Answer

Finally something people didn't answer in 10 seconds! I used your issue to continue to learn more about Powershell. The following works for me, I hope to see how others will slim down this code:

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" }

Note: I have changed the regular expression above from a period to a space immediately before the asterisk. This eliminates the risk of catching 'files' or 'dirs' or 'totals' in a filename/path. The original line is below for posterity.
jski 2014/07/16

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