Powershell 比较对象返回了错误的值

Powershell 比较对象返回了错误的值,powershell,compareobject,Powershell,Compareobject,我正在处理PowerShell脚本,而Compare-Objectcmdlet没有返回我期望的结果。我不会将整个脚本放在这里,但这是总体思路: $knownFiles = Import-Csv -Path "C:\knownfiles.csv" $currentFiles = Get-ChildItem -Path "\\file\share" $knownFileObject = $knownFiles | Select-Object -Property

我正在处理PowerShell脚本,而
Compare-Object
cmdlet没有返回我期望的结果。我不会将整个脚本放在这里,但这是总体思路:

$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
将不返回任何内容,如预期的那样。但是,使用以下示例:

$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 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
它将返回以下内容:

InputObject SideIndicator ----------- ------------- @{Name=file5.dat; Length=25137; LastWriteTimeUtc=1/3/2018 8:07:51 AM} => 输入对象侧指示器 ----------- ------------- @{Name=file5.dat;Length=25137;LastWriteTimeUtc=1/3/2018 8:07:51 AM}=> 它肯定会检测到两个对象之间存在差异,但它总是只返回最后一行,而不是不同的实际记录。如果有两个已更改的文件,则返回最后两行。如果我向
比较对象添加
“-property Name”
,它将返回正确的文件名,但我还需要查找大小和写入时间的差异。我可以使用
Export Csv
将这两个对象写回一个文件,然后在这些文件的
Get Content
上运行
Compare Object
,这非常有效,但我不想将两个文件写入磁盘,因为此作业将在不同的文件夹上每分钟运行数百次

编辑:根据其中一条建议,我还尝试了
比较对象-属性名称、长度、LastWriteTimeUtc
,当我这样做时,它将返回两个对象中的所有项,或者返回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
请注意,如果移动文件,
Compare Object
将不会注意到它具有这些属性。因此,如果您有C:\Folder\File.txt和D:\Folder\Folder2\File.txt,上面的
比较对象将不会注意到它。您必须创建一些相对路径属性来与进行比较以检测该属性。我只是指出这一点,因为这不止一次地咬到了我。我对
比较对象
产生了健康的厌恶。你必须非常具体,非常小心。没错,但在这种情况下可能不太相关,因为单个共享的内容与参考列表相比较,并且不涉及递归。我很早就专门尝试过这一点。如果我指定所有三个属性,那么它将返回100%的不匹配。换句话说,对于上面的示例,它将返回5个不匹配的项。另外,如果只比较LastWriteTimeUtc,它也会返回所有对象。这很可能是因为CSV中的
LastWriteTimeUtc
是一个字符串,而目录列表中的
LastWriteTimeUtc
是一个
DateTime
对象。这个答案是100%正确的。我真的弄明白了,然后来这里发布我的解决方案,但是是的,每个对象中的日期时间并不匹配,尽管显示是相同的。当我比较“$LastWriteTimeUtc.Ticks”时,值是不同的。
$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