compare-object排除超过x时间的文件

时间:2017-07-19 14:21:24

标签: powershell

我正在使用powershell脚本将文件从1个位置移动到另一个位置,然后我使用compare-object从两个位置获取哈希值,并在出现问题时发出信号。

由于get-hash花了很长时间(谈到多个数据),我想排除已经存在数小时/天的文件。

我的代码:

Compare-Object -ReferenceObject (dir $nas_smb_share -Recurse | Where-Object{!$_.psiscontainer} | get-hash) -differenceObject (dir $cs_dest -Recurse | Where-Object  {!$_.psiscontainer} | get-hash) |
%{if ($_.SideIndicator -eq "=>" ){$result = ("$($_.InputObject)")}}
if ([string]::IsNullOrEmpty($result)){$res = "Transfer succeeded without problems"}
else {$res = ("transfer failed on following file(s): "+ (dir $cs_dest -Recurse | Where-Object {!$_.psiscontainer } | get-hash | ? {$_.hashstring -match $result}) )}

输出是一个邮件,其文件哈希值已更改。

所以我想了解如何改变这一部分:

Compare-Object -ReferenceObject (dir $nas_smb_share -Recurse | Where-object{!$_.psiscontainer} | get-hash)

所以它只需要不超过例如1小时的文件/文件夹

2 个答案:

答案 0 :(得分:1)

您只需过滤where子句:

Compare-Object -ReferenceObject (dir $nas_smb_share -Recurse | Where-object{(!$_.psiscontainer) -AND ($_.LastWriteTime -gt (Get-Date).AddHours(-1))} | get-hash)

答案 1 :(得分:1)

EBGreen's answer为您按最后修改时间过滤问题提供了有效的解决方案。

让我使用更高效,简化的代码版本来补充它,这也解决了Compare-Object调用的概念性问题。

注意:由于使用Get-FileHash(v4 +)和Get-ChildItem -File(v3 +)以及简化的Where-Object语法(比较声明; v3 +),因此需要 PSv4 + )。

# Get current time stamp.
$now = Get-Date
# Determine the cut-off time span.
$ts = New-TimeSpan -Hours 1

# Construct the filtering script block to pass to Where-Object below,
# which filters in only those files whose last-modified time is equal to
# or less than the time span.
$sb = { $now - $_.LastWriteTime -le $ts }

# Construct the path wildcard expression that we'll use to filter the
# Compare-Object output to find the right-side-only differences.
# Note: Because we use Compare-Object -PassThru below in order to preserve
#       the [Microsoft.PowerShell.Commands.FileHashInfo] instances output by
#       Get-FileHash, we don't have acces to the .SideIndicator property.
$inRightSideSubtreePattern = (Convert-Path $cs_dest) + '/*'

# Compare the file hashes and return those that are different on the right side.
# * Note the use of -File to limit Get-ChildItem's output to files.
# * Note the use of -Property Hash to ensure that the actual hash values are
#   compared - without it, Compare-Object would simply compare the results of
#   calling .ToString() on the input objects, which would yield the static 
#   'Microsoft.PowerShell.Commands.FileHashInfo' string value, and no differences
#   would ever be found.
# * Since we do want access to the .Path property of the
#  [Microsoft.PowerShell.Commands.FileHashInfo] objects output Get-FileHash
#  later, we have no choice but to use -PassTru - otherwise, we'd get a 
#  [pscustomobject] with a .SideIndicator property and *only* a .Hash property.
# * Conversely, however, using -PassThru - which passes the input objects through
#   as-is - deprives of the .SideIndicator property, so the .Path property
#   is used to find the right-side-only results.
$result = Compare-Object -PassThru -Property Hash `
  (Get-ChildItem $nas_smb_share -File -Recurse | Where-Object $sb | Get-FileHash) `
  (Get-ChildItem $cs_dest -File -Recurse | Get-FileHash) |
    Where-Object Path -like $inRightSideSubtreePattern

# The [Microsoft.PowerShell.Commands.FileHashInfo] instances output by Get-FileHash
# have a .Path property containing the input file's full filename.
# Applying .Path to the $result as a whole will retrieve an array of the hashes'
# input filenames and, in a string context, concatenate them with spaces.
if ($result.Count -eq 0) {$res = "Transfer succeeded without problems"}
else                     {$res = "Transfer failed on following file(s): " + $result.Path }

# Output result.
$res