1

I have some problem with Compare-Object. My task is to get difference between two directory snapshots made at different times. First snapshot is taken like this:

ls -recurse d:\dir | export-clixml dir-20100129.xml 

Then, later, I get second snapshot and load both of them:

$b = (import-clixml dir-20100130.xml) 
$a = (import-clixml dir-20100129.xml) 

Next, I'm trying to compare with Compare-Object, like that:

diff $a $b 

What I get is in some places files that were added to $b since $a, but in some -- files that were in both snapshots, and some files, that were added to $b, are not given in Compare-Object output. Puzzling, but $b.count - $a.count is EXACTLY the same as (diff $a $b).count. Why is that?

Ok, Compare-Object has -property param. I try to use that:

diff -property fullname $a $b 

And I get the whole mess of differences: it shows me ALL the files. For example, say $a contains:

A\1.txt 
A\2.txt 
A\3.txt 

And $b contains:

X\2.mp3 
X\3.mp3 
X\4.mp3 
A\1.txt 
A\2.txt 
A\3.txt 

diff output is something like that:

X\2.mp3 => 
A\1.txt <= 
X\3.mp3 => 
A\2.txt <= 
X\4.mp3 => 
A\3.txt <= 
A\1.txt => 
A\2.txt => 
A\3.txt => 

Weird. I think I don't understand something crucial about Compare- Object usage, and manuals are scarce... Please, help me to get the DIFFERENCE between two directory snapshots. Thanks in advance

UPDATE: I've saved data as plain strings like that:

> import-clixml dir-20100129.xml | % { $_.fullname } | out-file -enc utf8 a.txt

And results are the same. Here're excerpts of both snapshots (top 100-something lines, a.txt and b.txt), output of compare-object, and output of UNIX diff (unified). All files are UTF-8: http://dl.dropbox.com/u/2873752/compare-object-problem.zip

4 Answers 4

2

One can solve the problem by using -SyncWindow parameter. The value should be half a length of a smallest collection in comparison:

> Compare-Object -SyncWindow ($a.length / 2) $a $b

Source: http://dmitrysotnikov.wordpress.com/2008/06/06/compare-object-gotcha/

1
  • 1
    Note that as of PowerShell v2, the -SyncWindow property has a default value of [int32]::MaxValue.
    – Bacon Bits
    May 8, 2015 at 14:01
1

This is due to the export-clixml/import-clixml. It actually changes the type of each file object from System.IO.FileSystemInfo to Deserialized.System.IO.FileInfo.

Have your second ls command export-clixml to a temporary file, then import and compare against that and it should fix the problem.

1
  • Actually, both snapshot are from Import-Clixml, sorry for misleading. I've corrected the question. But it has no effect, actually -- result is the same. Jan 30, 2010 at 8:37
1

A good example that I've found is this.

Get the original status for services:

$before = get-service

Now make some changes to the service, for example shut down 1 and start 1.

Get the new status for services:

$after = get-service

Then compare the two lists (diff is an alias for Compare-Object):

diff $before $after -property name,status

Examples results:

PS> diff $before $after -property name,status

name                                                                     status SideIndicator
----                                                                     ------ -------------
Spooler                                                                 Stopped =>
Spooler                                                                 Running <=

Demonstrates 1st object with the <=, 2nd object of the change seen with a =>. Or simply a before and after perspective. You could also create a label and expression to show the word "Changed" in the event there is a =>.

Using this you can also see in a comparison when something is in the first list but was in the second. Much like a find unmatch query.

1
  • To further improve the answer, try using the same context (a directly list) to answer the question. Nov 5, 2012 at 10:09
0

Personally, i find that diff works better if you can sort it first

Try

$b = (import-clixml dir-20100130.xml) | sort
$a = (import-clixml dir-20100129.xml) | sort
diff $a $b
1
  • get-alias diff would show its actually just Compare-Object
    – Matt
    Jun 12, 2019 at 18:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .