У меня есть быстрый сценарий, предназначенный для сравнения различий в файлах на разных серверах, а затем подсказка, нужно ли зеркалировать изменения. Я бы хотел, чтобы он разумно НЕ запрашивал копирование, если нет никаких изменений.
Сценарий:
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!" }
Я бы хотел, чтобы Powershell не запрашивал продолжение, если Robocopy сообщает 0 для Mismatch, Failed, Extras и Copied. Это не очень важно для этого конкретного проекта, но я могу придумать пару полезных применений для такой проверки. Спасибо!
Наконец то, что люди не ответили через 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 (Всего | Каталоги | Файлы) \ b) ((?! Файлы).)$ '
Я понимаю, что это более старый поток, но обратите внимание, что это также можно сделать с помощью кода выхода, возвращаемого robocopy, чтобы определить, существуют ли какие-либо изменения (значение 0 указывает на отсутствие изменений). Сделать это можно двумя способами:
$RobocopyResult = Start-Process -FilePath robocopy -ArgumentList $RobocopyParams -Wait -PassThru $RobocopyResult.ExitCode
При использовании Start-Process важно использовать -PassThru, иначе в $ RobocopyResult не будет установлено значение.
Другие коды выхода перечислены на http://ss64.com/nt/robocopy-exit.html.
Вот мой совет. Мой код читает файл журнала и ищет строки, соответствующие полям сводки. Затем он разбирает его на два объекта, которые содержат статистику для файлов и для каталогов:
### 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