Comparing Two Files with PowerShell

James TaralaBaselining, Windows Auditing

One of the concepts that we have written about over and over again on this blog is the principal of baselining and how to compare the present state of a system with a known good snapshot of the same attribute of a system. If for instance we have a server with 10 running services on it today, and tomorrow we examine the system and discover that there are 11 running services, then something just isn’t right. In the immortal words of Sesame Street, “One of these things is not like the other. One of these things are not the same…”

So let’s say you have a baseline created for some attribute of an operating system. How would you go about doing a comparison of a snapshot you took earlier and one that you just took? To start let’s assume that these snapshots are text based. If they are binary snapshots then we have a whole different set of issues to worry about. But assuming the two snapshots are the output of the same command (just taken at a different time) and the output is text based, then we’re in business.

If you’re working with a Unix / Linux system, then you would definitely reach for the stalwart DIFF utility. It’s been around forever and it is a system administrator’s favorite.

With Microsoft PowerShell though we have to make a decision. The DIFF binary is not available in PowerShell (although there is a DIFF alias). However there are two commands that are built into Windows and that have been available since the days of CMD.EXE. These two built in commands are FC.EXE and COMP.EXE. Unfortunately both of them tend to be unreliable and give strange results when using them for baselining. So what else can we do?

Thankfully PowerShell has introduced the cmdlet COMPARE-OBJECT (and yes, as you guessed, DIFF is an alias to this cmdlet). With PowerShell, you can take two objects, give them to COMPARE-OBJECT, and it will give you a comparison between the two objects. These objects can be anything, but for our purposes we will be focusing on text files. But there’s nothing to say you could not compare user accounts from Active Directory, Registry Keys, or any other objects.

The syntax for the command is:

Compare-object object1 object2

However there is one gotcha. If you compare two text files this way, then the cmdlet will simply say, “Yes, the name of the text files file1.txt and file2.txt are different.” So if you want to compare the content of two text files there is an extra step to take. You have to introduce the GET-CONTENT cmdlet in order to compare the content of the two files. Therefore the new (and usable) syntax would work like this:

Compare-object (get-content file1.txt) (get-content file2.txt)

The results of this command will show you the side indicator of what is different between the two files and in which of the two files the added text exists in. It’s kind of a funny arrow based system, but it’s easy enough to understand.

Now you should be all set. So if you have been getting in the habit of baselining your systems, then these commands might be useful when you are trying to automate a comparison between two snapshots. Next you probably want to automate things further with a command line email utility (I like the built in PowerShell capabilities