Powershell 比较对象返回了错误的值
我正在处理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
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