【问题标题】:Using powershell to copy new and updated files使用 powershell 复制新文件和更新文件
【发布时间】:2017-09-19 14:55:41
【问题描述】:

当谈到 powershell 时,我是一个完全的新手,但是我得到了一个我需要改进的脚本,以便我们可以将更新的或新的文件从一个服务器移动到另一个服务器。我已经设法掌握了当前的脚本,但正在努力寻找正确的 cmdlet 和参数来实现所需的行为。

我的脚本成功地检测到更改的文件并将它们移动到准备传输到另一台服务器的位置,但它没有检测到任何新文件。

谁能给我一些关于如何实现这两种行为的指导?

$CurrentLocation = "C:\current"
$PreviousLocation = "C:\prev"
$DeltaLocation = "C:\delta"

$source = @{}

#
# Get the Current Location file information
#
Get-ChildItem -recurse $CurrentLocation | Foreach-Object {
    if ($_.PSIsContainer) { return }
    $source.Add($_.FullName.Replace($CurrentLocation, ""), $_.LastWriteTime.ToString())
}
Write-Host "Content of Source"
$source

$changesDelta = @{}
$changesPrevious = @{}

#
# Get the Previous Directory contents and compare the dates against the Current Directory contents 
#
Get-ChildItem -recurse $PreviousLocation | Foreach-Object {
    if ($_.PSIsContainer) { return }
    $File = $_.FullName.Replace($PreviousLocation, "")
    if ($source.ContainsKey($File)) {
        if ($source.Get_Item($File) -ne $_.LastWriteTime.ToString()) {
            $changesDelta.Add($CurrentLocation+$File, $DeltaLocation+$File)
            $changesPrevious.Add($CurrentLocation+$File, $PreviousLocation+$File)
        }
    }
}
Write-Host "Content of changesDelta:"
$changesDelta
Write-Host "Content of changesPrevious:"
$changesPrevious

#
# Copy the files into a temporary directory
#
foreach ($key in $changesDelta.Keys) {
    New-Item -ItemType File -Path $changesDelta.Get_Item($key) -Force
    Copy-Item $key $changesDelta.Get_Item($key) -Force
}
Write-Host $changesDelta.Count "Files copied to" $DeltaLocation

#
# Copy the files into the Previous Location to match the Current Location
#
foreach ($key in $changesPrevious.Keys) {
    Copy-Item $key $changesDelta.Get_Item($key) -Force
}

【问题讨论】:

  • 如果这是一个脚本文件,我会在您调用已知 cmdlet 参数时明确说明,例如 Get-ChildItem -Path-LiteralPath 如果您不希望通配符通过。此外,在您的If ($_ 子句中,您应该使用Continue 而不是Return,因此它仍会处理管道的其余部分。只是一些观察,因为我不了解您的最终目标。与什么相比发生了变化?
  • 抱歉,我认为我说得不够清楚。我们想比较一段时间后文件的状态。这将用于移动新的更新文件或更改的更新文件。因此,与“上一个目录”相比,该脚本需要检测“当前目录”中的新文件以及“当前”与“上一个”相比对“当前”文件的任何更改,然后需要将这些文件复制到“临时”增量'目录。是不是清楚一点?
  • 那么文件是否以某种方式重复,您正在与之进行比较?您是只查看更新的文件,还是同时查看新文件?
  • 我们正在将“当前”中的文件与“以前”中的文件进行比较。我们想通过比较显示“previous”中没有相应的文件来知道“current”中何时有新文件。然后,我们还想查看最后写入时间时间戳以确定文件是否已更改。一旦脚本变得有趣,最后的任务是将新文件和更新文件复制到“delta”目录和“previous”目录中,以便“previous”和“current”匹配。
  • 现在我明白你的问题了。给我几个,我会给你一个答案。

标签: powershell delta


【解决方案1】:

这是满足您需求的一种简化方法。需要注意的一点是,我使用的一些构造需要PSv3+。这复制目录结构,只是复制文件。此外,它会比较可能会或可能不会做您想要的基本名称(忽略扩展名)。它可以通过使用.Name 而不是.BaseName 来扩展以包含扩展

#requires -Version 3

$CurrentLocation  = 'C:\current'
$PreviousLocation = 'C:\prev'
$DeltaLocation    = 'C:\delta'

$Current  = Get-ChildItem -LiteralPath $CurrentLocation -Recurse -File
$Previous = Get-ChildItem -LiteralPath $PreviousLocation -Recurse -File

ForEach ($File in $Current)
{
    If ($File.BaseName -in $Previous.BaseName)
    {
        If ($File.LastWriteTime -gt ($Previous | Where-Object { $_.BaseName -eq $File.BaseName }).LastWriteTime)
        {
            Write-Output "File has been updated: $($File.FullName)"
            Copy-Item -LiteralPath $File.FullName -Destination $DeltaLocation
        }
    }
    Else
    {
        Write-Output "New file detected: $($File.FullName)"
        Copy-Item -LiteralPath $File.FullName -Destination $DeltaLocation
    }
}

Copy-Item -Path "$DeltaLocation\*" -Destination $PreviousLocation -Force

【讨论】:

  • 谢谢。它似乎完成了这项工作,但是我现在遇到了一个问题,我得到以下输出:“无法将“System.Object []”类型的“System.Object []”值转换为“System.DateTime”类型。 "这与 If ($File.LastWriteTime... 行有关,我完全不知道为什么它不能进行转换。
  • @matt_isbell 这可能意味着您遇到了重复的碱基名称,并且它正在尝试进行组比较
  • 嗯,基本名称是否包含文件扩展名?我们尝试移动的文件是 AV 更新文件,因此文件名可能相同但扩展名不同。
  • @matt_isbell 正确。 .Name 包括我在答案中提到的扩展。
  • 啊,是的!那将教我阅读整本书!!!对不起。感谢您的所有帮助。
猜你喜欢
  • 2016-09-29
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 2016-06-22
  • 2018-11-11
  • 1970-01-01
相关资源
最近更新 更多