Como obter informações resumidas de robocopy envolvidas no powershell?

7

Eu tenho um script rápido escrito para comparar as diferenças de arquivos entre os servidores e, em seguida, faço uma solicitação para espelhar as alterações. Eu gostaria que ele inteligente não solicitar cópia se não houver alterações.

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

Eu gostaria que o Powershell não pedisse para continuar se o Robocopy relatasse 0 para Incompatibilidade, Falha, Extras e Copiado. Não é muito importante para este projeto em particular, mas posso pensar em alguns usos úteis para essa verificação. Obrigado!

    
por jski 11.07.2014 / 17:30

3 respostas

6

Finalmente, as pessoas não responderam em 10 segundos! Usei seu problema para continuar aprendendo mais sobre o Powershell. O seguinte funciona para mim, espero ver como os outros irão reduzir este código:

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

Observação: mudei a expressão regular acima de um período para um espaço imediatamente anterior ao asterisco. Isso elimina o risco de capturar 'arquivos' ou 'dirs' ou 'totais' em um nome de arquivo / caminho. A linha original está abaixo para a posteridade.
jski 2014/07/16

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

    
por 11.07.2014 / 21:06
2

Eu percebo que este é um segmento mais antigo, mas note que isso também pode ser feito usando o código de saída retornado pelo robocopy para determinar se existem quaisquer alterações (um valor de 0 indica nenhuma alteração). Existem duas maneiras de fazer isso:

  1. Execute sua instrução robocopy acima e, na próxima linha, verifique o valor de $ LastExitCode.
  2. Use o processo de início:
$RobocopyResult = Start-Process -FilePath robocopy -ArgumentList $RobocopyParams -Wait -PassThru
$RobocopyResult.ExitCode

Se estiver usando Start-Process, é importante usar -PassThru, caso contrário, nenhum valor será definido em $ RobocopyResult.

Outros códigos de saída estão listados no link .

    
por 03.09.2015 / 02:40
0

Aqui está o meu hack para isso. Meu código lê o arquivo de logs e procura as linhas que correspondem aos campos de resumo. Em seguida, ele é analisado em dois objetos que contêm as estatísticas dos arquivos e dos diretórios:

        ### 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
    
por 14.04.2017 / 00:31