比较对象返回错误值

Compare-Object is returning the wrong value

我正在处理 PowerShell 脚本,Compare-Object cmdlet 不是我所期望的 returning。我不会把整个脚本放在这里,但这是总体思路:

$knownFiles = Import-Csv -Path "C:\knownfiles.csv"
$currentFiles = Get-ChildItem -Path "\file\share"
$knownFileObject = $knownFiles |
                   Select-Object -Property Name, Length, LastWriteTimeUTC |
                   Sort-Object -Property Name
$currentFileObject = $currentFiles |
                     Select-Object -Property Name, Length, LastWriteTimeUTC |
                     Sort-Object -Property Name

现在,我有两个已排序的 PSCustomObjects,其中包含一组文件的名称、长度和上次写入时间。这是我想不通的。

如果对象相同,Compare-Object return不出所料。但是,使用下面的示例:

$knownFileObject 看起来像这样:

Name          Length     LastWriteTimeUtc
----          ------     ----------------
file1.dat     38988     1/1/2018 8:04:57 AM
file2.dat     7182      1/2/2017 8:03:24 AM
file4.dat     1026      1/3/2017 8:04:20 AM
file5.dat     25137     1/3/2018 8:07:51 AM

$currentFileObject 看起来像这样:

Name          Length     LastWriteTimeUtc
----          ------     ----------------
file1.dat     38988     1/1/2018 8:04:57 AM
file2.dat     7182      1/2/2017 8:03:24 AM
file3.dat     1026      1/2/2018 8:04:30 AM
file4.dat     1026      1/3/2017 8:04:20 AM
file5.dat     25137     1/3/2018 8:07:51 AM

如果我运行

Compare-Object -ReferenceObject $knownFileObject -DifferenceObject $currentFileObject

它会 return 这个:

InputObject                                                            SideIndicator
-----------                                                            -------------
@{Name=file5.dat; Length=25137; LastWriteTimeUtc=1/3/2018 8:07:51 AM}  =>

它确实检测到两个对象之间存在差异,但它始终只是 return 最后一行,而不是不同的实际记录。如果有两个更改的文件,则 return 是最后两行。如果我将 "-property Name" 添加到 Compare-Object,它 return 是正确的文件名,但我还需要查找大小和写入时间的差异。我可以使用 Export-Csv 将两个对象写回一个文件,然后在这些文件的 Get-Content 上使用 运行 Compare-Object,效果很好,但我不知道我想将两个文件写入磁盘,因为此作业每分钟将 运行在不同的文件夹上执行数百次。

编辑: 根据其中一个建议,我也尝试了 Compare-Object ... -Property Name, Length, LastWriteTimeUtc,当我这样做时,它 return 中的每个项目两个对象,或者 100% 不匹配。

我做错了什么?

指定要用来比较对象的属性:

Compare-Object $knownFileObject $currentFileObject -Property Name, Length, LastWriteTimeUtc

您还需要确保您比较的是同一事物。您的方法的问题是 FileInfo 对象的 LastWriteTimeUtc 属性 是一个 DateTime 对象,它具有亚秒精度:

PS C:\> Get-Date| Format-List *

DisplayHint : DateTime
DateTime    : Donnerstag, 25. Januar 2018 16:31:07
Date        : 25.01.2018 00:00:00
Day         : 25
DayOfWeek   : Thursday
DayOfYear   : 25
Hour        : 16
Kind        : Local
Millisecond : 268          ← this here
Minute      : 31
Month       : 1
Second      : 7
Ticks       : 636524946672682859
TimeOfDay   : 16:31:07.2682859
Year        : 2018

但是您的 CSV 中的时间戳是精度限制为秒的字符串,因此原始时间戳和存储的时间戳之间可能存在微小差异。

在您的情况下,最好的方法是以定义的格式(例如长 ISO 格式)存储时间戳,并对目录列表中的时间戳使用相同的格式。顺便说一句,不需要对数组进行排序,因此您可以放弃该步骤。

$saved   = Import-Csv 'C:\knownfiles.csv' |
           Select-Object Name, Length, LastWriteTimeUtc
$current = Get-ChildItem '\server\share' |
           Select-Object Name, Length,
               @{n='LastWriteTimeUtc';e={$_.LastWriteTimeUtc.ToString('s')}}

Compare-Object $saved $current -Property Name, Length, LastWriteTimeUtc