我正在使用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小时的文件/文件夹
答案 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