Как синхронизировать 2 акции на LastWriteTime без удаления - PullRequest
0 голосов
/ 16 мая 2019

Мне нужно синхронизировать 2 репертуара FTP на 2 разных серверах, которые не являются членами IIS кластера. Виртуальный IP-адрес используется для переключения при сбое.

enter image description here

Я пытался использовать robocopy или xcopy, чтобы иметь справочный каталог. В моем случае, когда задача запускается третьим сервером, мне просто нужно скопировать последние записанные файлы и каталог, которых нет на другом.

$Global:pathFTP1 = $SRV1unc + "\c$\inetpub\PlcmSpIp"
$Global:pathFTP2 = $SRV2unc + "\c$\inetpub\PlcmSpIp"
$Global:Files1 = @()
$Global:Files2 = @()
$Global:tSRV = @(
    New-Object PSObject -Property @{Serveur = $SRV1; RacineFTP = $pathFTP1; Fichiers = $Files1}
    New-Object PSObject -Property @{Serveur = $SRV2; RacineFTP = $pathFTP2; Fichiers = $Files2}
)

Вот часть кода:

$Global:Component = "Tree"
$Comparison = Compare-Object -ReferenceObject $tSRV.Item(0).Fichiers -DifferenceObject $tSRV.Item(1).Fichiers -PassThru -IncludeEqual
$ComparisonFolders = $Comparison | Where-Object{$_.PSIsContainer -eq $true}
$FoldersPresentOnEach = $ComparisonFolders | Where-Object {($_.SideIndicator -eq "==") -and (Test-Path($_.FullName))}
$FoldersNotPresentInSRV1 = $ComparisonFolders | Where-Object {($_.SideIndicator -eq "=>") -and (Test-Path($_.FullName))}
$FoldersNotPresentInSRV2 = $ComparisonFolders | Where-Object {($_.SideIndicator -eq "<=") -and (Test-Path($_.FullName))}
##Folders not present on $SRV1
if ($FoldersNotPresentInSRV1.Count -ne 0) {
    foreach ($Folder in $FoldersNotPresentInSRV1) {
        if (-not (Test-Path (($Folder.Fullname.Replace($SRV2unc,$SRV1unc)).Replace('\\\','\\')))) {
            New-Item -ItemType Directory -Path (($Folder.Fullname.Replace($SRV2unc,$SRV1unc)).Replace('\\\','\\')) -Force -ErrorAction SilentlyContinue
       }
    }
}
##Folders not present on $SRV2
if ($FoldersNotPresentInSRV2.Count -ne 0) {
    foreach ($Folder in $FoldersNotPresentInSRV2) {
        if (-not (Test-Path (($Folder.Fullname.Replace($SRV2unc,$SRV1unc)).Replace('\\\','\\')))) {
            New-Item  -ItemType Directory -Path (($Folder.Fullname.Replace($SRV1unc,$SRV2unc)).Replace('\\\','\\')) -Force -ErrorAction SilentlyContinue
        }
    }
}

##Files comparison
$ComparisonFiles = $Comparison | Where-Object {$_.PSIsContainer -eq $false}
$FilesPresentOnEach = $ComparisonFiles | Where-Object {($_.SideIndicator -eq "==")  -and ($_.LastWriteTime -eq (($_.Directory.Fullname.Replace($SRV2unc,$SRV1unc)).Replace('\\\','\\')).LastWriteTime)}
$FilesNotPresentInSRV1 = $ComparisonFiles | Where-Object {($_.SideIndicator -eq "=>") -and ((Test-Path($_.Directory.Fullname.Replace($SRV2unc,$SRV1unc)).Replace('\\\','\\')))}
$FilesNotPresentInSRV2 = $ComparisonFiles | Where-Object {($_.SideIndicator -eq "<=") -and ((Test-Path($_.Directory.Fullname.Replace($SRV2unc,$SRV1unc)).Replace('\\\','\\')))}
## Files not present on $SRV1
if ($FilesNotPresentInSRV1.Count -ne 0) {
    foreach ($File in $FilesNotPresentInSRV1) {
        Copy-Item -Path $File.FullName -Destination (($File.Directory.Fullname.Replace($SRV2unc,$SRV1unc)).Replace('\\\','\\')) -Force -ErrorAction SilentlyContinue
    }
}
##Files not present on $SRV2
if ($FilesNotPresentInSRV2.Count -ne 0) {
    foreach ($File in $FilesNotPresentInSRV2) {
        Copy-Item -Path $File.FullName -Destination (($File.Directory.Fullname.Replace($SRV1unc,$SRV2unc)).Replace('\\\','\\')) -Force -ErrorAction SilentlyContinue
    }
}
$Global:Component = "Files already present"
if ($FilesPresentOnEach.Count -ne 0) {
    foreach ($File in $FilesPresentOnEach | Where {$_.LastWriteTime -gt (Get-Item(($_.FullName.Replace($SRV1unc,$SRV2unc)).Replace('\\\','\\'))).LastWriteTime}) {
        Copy-Item -Path $File.FullName -Destination (($File.Fullname.Replace($SRV1unc,$SRV2unc)).Replace('\\\','\\')) -Force -ErrorAction SilentlyContinue       
    }
    foreach ($File in $FilesPresentOnEach | Where {$_.LastWriteTime -lt (Get-Item(($_.FullName.Replace($SRV1unc,$SRV2unc)).Replace('\\\','\\'))).LastWriteTime}) {  
        Copy-Item -Path (($File.Fullname.Replace($SRV1unc,$SRV2unc)).Replace('\\\','\\')) -Destination $File.FullName -Force -ErrorAction SilentlyContinue
    }
}

Я ожидаю, что файлы, в которых атрибут LastWriteTime самого нового скопирован на другой, уже существуют и старше или, если они не существуют. На самом деле некоторые папки не копируются и не работают должным образом.

Вместо того, чтобы переписать путь с помощью replace, как я могу сделать это правильно? Может быть, я неправильно понял проблему и сделал это другим инструментом?

1 Ответ

0 голосов
/ 17 мая 2019

Зачем делать это проще, когда можно усложнять - Шадокс

Благодаря Ansgar Wiechers, использование Robocopy без зеркала - это самый простой способ решения задачи.

robocopy $pathFTP2 $pathFTP1 /E /ZB /X /COPYALL /XO /FFT /LOG:$ficROBOCOPY
robocopy $pathFTP1 $pathFTP2 /E /ZB /X /COPYALL /XO /FFT /LOG+:$ficROBOCOPY

Мне приходится иметь дело с учетной записью gMSA, чтобы запустить задачу, и ошибка такого типа:

System.Management.Automation.ParameterBindingArgumentTransformationException: Невозможно обработать преобразование аргумента для параметра 'Value',Невозможно преобразовать значение в тип System.String.---> System.Management.Automation.ArgumentTransformationMetadataException: невозможно преобразовать значение в тип System.String.---> System.Management.Automation.PSInvalidCastException: Невозможно преобразовать значение в тип System.String.в System.Management.Automation.ArgumentTypeConverterAttribute.Transform (EngineIntrinsics engineIntrinsics, Object inputData, Boolean bindingParameters, Boolean bindingScriptCmdlet) --- Конец внутренней трассировки стека исключений ---
в System.Management.Automation.ArgumentformIt (engineIntrinsics, Object inputData, Boolean bindingParameters, Boolean bindingScriptCmdlet) в System.Management.Automation.ParameterBinderBase.BindParameter (CommandParameterInternal параметр, параметр CompiledCommandParameterMetadata, флаги ParameterBindingFlags) --- Конец внутреннего исключения стека.ExceptionHandlingOps.CheckActionPreference (FunctionContext funcContext, исключение) в System.Management.Automation.Interpreter.ActionCallInstruction`2.Run (фрейм InterpretedFrame) в System.Management.Automation.Interpreter.EnterTryCatchFunmeInpre..Interpreter.EnterTryCatchFinallyInstruction.Run (кадр InterpretedFrame)

Но это другая проблема ...

...