检查文件夹以确保使用PowerShell完全下载内容

时间:2016-01-06 15:16:22

标签: powershell

我正在寻找PowerShell解决方案。我们有一台服务器,其中一些软件将一些文件夹下载到名为“接收”的文件夹中。'这些内部文件夹可能包含1个或多个文件。我有一个监视Receive文件夹的脚本,并将所有子文件夹(包括其数据)从该服务器移动到另一个位置。我已安排我的脚本每10分钟执行一次。但是我观察到,在移动数据之后,通常会有一些文件夹'文件已损坏或某些文件丢失。

我们有什么方法可以检查数据是否被复制到远程文件夹中,并且脚本可以忽略该数据以用于下一次出现?

4 个答案:

答案 0 :(得分:0)

假设目录"接收"在"。"

假设未保留接收目录/文件的时间戳。

我会检查写入目录的最后一个文件是否超过20分钟。这个时间直接被我用作10分钟频率的一半,以便完全接收单批文件。实际上,应根据您的数据量和频率来决定。

$recvDirs = (gci .\Receive)
$ageInSec = 1200
$refTime = get-date
foreach ($dir in $recvDirs) {

    $dir | add-member childLastWriteTime $dir.LastWriteTime
    foreach ($child in (gci $dir.fullname)) {

        # since $dir.lastwritetime is always = $child.lastwritetime
        foreach ($grandChild in (gci $child.fullname -recurse)) {

            if ($grandChild.lastWriteTime -gt $dir.childLastWriteTime) {

                $dir.childLastWriteTime = $grandChild.lastWriteTime
            }
        }
    }

    write-host $dir ": " $dir.childLastWriteTime
    if (($refTime - $dir.childLastWriteTime).TotalSeconds -gt $ageInSec) {

        write-host "moving " $dir "..."
        # do your move
    }
}

为了更安全的方法,如果您可以控制接收数据,您应该有一个传输结束信号/文件或校验和文件/信息来验证完整性。

答案 1 :(得分:0)

我建议使用Get-FileHash确保副本与原始副本匹配。如果文件丢失,它会给出错误,如果文件从原始文件和复制文件生成相同的散列,则指示文件是否完全下载且未损坏。默认的哈希算法是SHA256。如果您有可用的话,请查看robocopy.exe

使用Get-FileHash的示例提示:

$source = "\\server\path-to-files\"
$destination = "\\server2\destination-of-files\"
$files = Get-Childitem $source -File
$time = (Get-Date -Format "dd-MM-yyyy-HH-mm-ss").ToString()
$loglocation = "C:\logs\"+"$time"+".txt"
$files | foreach {
                  $copiedfile = "$destination"+"$_"
                  $originalhash = (get-filehash $_.FullName).Hash
                  $copyhash = (get-filehash $copiedfile).Hash
                  if ($originalhash -eq $copyhash){
                                                  "'$_','Passed'" >> $loglocation
                                                  }
                  else {
                       "'$_','Retried'" >> $loglocation
                      ##Put copy command here
                       }
                  }

答案 2 :(得分:0)

所以,实际上,在您同步未完全下载的文件和同步不完整的文件列表时,您会遇到这些大问题。如果您使用的是Linux,则可以使用incron并查找IN_FILE_CLOSE事件,该事件告诉您文件已关闭以进行写入,并根据该事件触发同步,但它可能仍然无法帮助您的子文件夹-architecture方法。

最好的方法是修改将内容转储到此文件夹的软件。但是,在很多情况下,您可能无法做到这一点。

下一个最佳方法包括查看最后修改时间和仅移动最近修改过的内容,可能是一天左右,也许更少。

如果您确实需要将它们发送到远程服务器,那么我建议分离关注点以解决这两个问题:首先,一些守护进程将文件夹F从.\Receive\移动到{ {1}},表示上传的完整性,然后另一个守护程序在交错的时间工作可能会尝试将内容从.\Archiving\发送到远程服务器,进行实际的远程备份。一个好的脚本会尝试发送它,然后将文件夹移动到.\Archiving\,其他脚本将检查"这是否成功上传,文件长度是否匹配,加密哈希或CRC匹配?&#34 ;在删除本地副本之前:如果哈希不匹配,而不是删除,则只需移至.\Verify-Archival\并让另一个守护程序再次尝试。

如果您需要释放移动文件(从.\Archiving\.\Receive\)和删除文件夹,您也可以分开关注点.\Archiving\中的空格很快。在.\Receive\下创建新文件夹(如果它不存在)会非常快,移动文件将是原子文件,一旦文件消失,我们可以将子文件夹保留一天到位#34;如果有人未上传。"然后删除所有在一天内保持空白的子文件夹,同时清理它们。

答案 3 :(得分:0)

我认为文件没有损坏,因为复制过程中出现错误(你可以像Booga Roo那样计算哈希值,但是因为你正在复制首先没有完全下载的文件)。如果您要在原始位置打开这些文件,您会收到类似的错误(='接收'文件夹)。

可能很难对此进行验证,因为当您发现文件在复制位置已损坏时,可以将文件完全下载到原始位置。

我会尝试打开每个文件以便写入'在复制之前。如果文件仍在下载,则文件系统中的文件会有写锁定,因此您无法打开它以进行“写入”。

如果你可以打开它来写''你关闭它并复制它,如果你不能跳过它并在下次运行时再试一次。