如何在不删除的情况下同步 LastWriteTime 上的 2 个共享

How to sync 2 shares on LastWriteTime without deletion

我需要在 2 个不属于群集 IIS 的不同服务器后面同步 2 个 FTP 库。虚拟 IP 用于进行故障转移。

我尝试使用 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 重写路径,我怎样才能正确地做到这一点? 也许我以错误的方式解决问题并使用其他工具来解决问题?

既然可以把事情搞复杂,为什么还要搞简单 - Shadoks

感谢 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: Cannot process argument transformation on parameter 'Value'. Cannot convert value to type System.String. ---> System.Management.Automation.ArgumentTransformationMetadataException: Cannot convert value to type System.String. ---> System.Management.Automation.PSInvalidCastException: Cannot convert value to type System.String. at System.Management.Automation.ArgumentTypeConverterAttribute.Transform(EngineIntrinsics engineIntrinsics, Object inputData, Boolean bindingParameters, Boolean bindingScriptCmdlet) --- End of inner exception stack trace ---
at System.Management.Automation.ArgumentTypeConverterAttribute.Transform(EngineIntrinsics engineIntrinsics, Object inputData, Boolean bindingParameters, Boolean bindingScriptCmdlet) at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags) --- End of inner exception stack trace --- at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception) at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

但这是另一个问题...