我正在使用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
$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
它会返回:
InputObject SideIndicator ----------- ------------- @{Name=file5.dat; Length=25137; LastWriteTimeUtc=1/3/2018 8:07:51 AM} =>
它肯定会检测到两个对象之间存在差异,但它总是只返回最后一行,而不是实际记录的不同。如果有两个已更改的文件,则返回最后两行。如果我向"-property Name"
添加Compare-Object
,它会返回正确的文件名,但我还需要查找大小和写入时间的差异。我可以使用Export-Csv
将两个对象写回文件,然后在这些文件的Compare-Object
上运行Get-Content
,这样做效果很好,但我不知道想要将两个文件写入磁盘,因为这个作业将在不同文件夹上每分钟运行数百次。
编辑:根据其中一条建议,我还尝试了Compare-Object ... -Property Name, Length, LastWriteTimeUtc
,当我这样做时,它会返回两个对象中的每个项目,或100%不匹配
我做错了什么?
答案 0 :(得分:2)
指定要比较对象的属性:
Compare-Object $knownFileObject $currentFileObject -Property Name, Length, LastWriteTimeUtc
您还需要确保比较同样的事情。您的方法的问题是LastWriteTimeUtc
对象的FileInfo
属性是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格式)存储时间戳,并使用相同的格式作为目录列表中的时间戳。 BTW不需要对数组进行排序,因此您可以放弃该步骤。
$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