1

我正在处理 PowerShell 脚本,但Compare-Objectcmdlet 没有返回我所期望的。我不会把整个脚本放在这里,但这是一般的想法:

$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看起来像这样:

名称长度 LastWriteTimeUtc
---- ------ ----------------
文件 1.dat 38988 2018 年 1 月 1 日上午 8:04:57
file2.dat 7182 2017 年 1 月 2 日上午 8:03:24
file4.dat 1026 2017 年 1 月 3 日上午 8 点 04 分 20 秒
文件 5.dat 25137 2018 年 1 月 3 日上午 8:07:51

$currentFileObject看起来像这样:

名称长度 LastWriteTimeUtc
---- ------ ----------------
文件 1.dat 38988 2018 年 1 月 1 日上午 8:04:57
file2.dat 7182 2017 年 1 月 2 日上午 8:03:24
文件 3.dat 1026 2018 年 1 月 2 日上午 8:04:30
file4.dat 1026 2017 年 1 月 3 日上午 8 点 04 分 20 秒
文件 5.dat 25137 2018 年 1 月 3 日上午 8:07:51

如果我跑

Compare-Object -ReferenceObject $knownFileObject -DifferenceObject $currentFileObject

它会返回这个:

InputObject SideIndicator
------------ -------------
@{名称=file5.dat; 长度=25137;LastWriteTimeUtc=1/3/2018 8:07:51 AM} =>

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

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

我究竟做错了什么?

4

1 回答 1

3

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

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

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

PS C:\>获取日期| 格式列表 *

显示提示:日期时间
日期时间:Donnerstag,2018 年 1 月 25 日 16:31:07
日期:25.01.2018 00:00:00
天 : 25
DayOfWeek : 星期四
日期:25
小时 : 16
种类:本地
毫秒:268 ← 这里
分钟 : 31
月 : 1
第二:7
滴答声:636524946672682859
时间:16:31:07.2682859
年份 : 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
于 2018-01-24T22:37:54.593 回答