Ezine 163 – Employ Compare-Object to Evaluate Differences

Ezine 163 – Employ Compare-Object to Evaluate Differences

It is surprising how often when we troubleshoot computer problems it’s helpful to compare two files.  What I have in mind is playing detective where I examine the ‘before’ and the ‘after’ a crucial event.

Topics for PowerShell’s Compare-Object

 ♣

This Week’s Secret

This week’s PowerShell secret is never miss a chance to examine parameters in general and  -syncWindow in particular.  Always take the opportunity to study the parameters of any new PowerShell command;  I guarantee that whenever you try ‘help verb-noun’ with the -full switch, you will learn something useful. 

Here is an example: when I created a script featuring compare-Object the list of differences was much smaller than I anticipated.  Moreover, I knew there were differences between the two files which were not showing up in the output.  Once I discovered compare-Object had a switch called -syncWindow, I got a complete list of all the differences – problem solved.

Guy’s Mission to Generate a List of Differences

In this mission I had a directory of files.  Some of those files were missing a phrase, I wanted a list of files with these deficiencies.  Stage one was to create a text file containing a directory listing.  Stage two was to create another file listing only those files containing a particular phrase.  Stage three was to call for compare-Object, process the two files and create a third file with a list of all the files that were missing my particular phrase.  In these ezine I just want to focus on stage three, generating a list of differences.

Preamble, Call for Help

This script is a useful reminder to see compare-Object’s parameters.

# Microsoft PowerShell script to research compare-Object
# Author: Guy Thomas
# Version 1.1 April 2008 tested on PowerShell v 1.0

help compare-Object -full

Note 1:  With compare-Object, the two required parameters are -referenceObject and -differenceObject.  In most examples -referenceObject controls the master content, which holds ALL the information, while -differenceObject has the ‘after the event’, or ‘second’ file.   Also note what help says about these parameters, what we learn is that that the position of these parameters is important, reference list first, difference list second.

Note 2:  In a production script we employ get-Content to open the file and read it.  What I do is assign this part of the script to a variable, for example $strReference = get-Content "D:\scripts\list.txt"

Note 3:  Please make note of other parameters such as -includeEqual and -syncWindow.

Example 1: To Compare Two Files, and List Differences

For the sake of clarity, and so that we focus on compare-Object, I have scaled down our mission to just tackle comparing two files.  The best way to understand my example is if you immerse yourself in my shopping list scenario.

Preparation
We need two files, the first for reference, the second to compare.  Let us use a shopping list for our test scenario.  The file called BeforeShopList.txt is a list of goods we should buy at the supermarket.  AfterShopCheckout.txt, is a list of what we actually bought.

BeforeShopList: Save these 7 items into a text file, I called mine C:\temp\BeforeShopList.txt

Oranges
Bananas
Cucumbers
Lettuce
Burgers
Sausages
Chips

AfterShopCheckout: Save these 6 items into a text file, I called mine C:\temp\AfterShopCheckout.txt

Oranges
Bananas
Lettuce
Sausages
Chips
Ice-Cream

Now we are ready to execute this compare-Object script.  My favoured method is to save these instructions into a cmdlet with a .ps1 extension, then call the file from the PowerShell command line.  Alternatively, copy the following lines and then paste into the command line.

# Microsoft PowerShell script to research compare-Object
# Author: Guy Thomas
# Version 1.1 April 2008 tested on PowerShell v 1.0

clear-host
$strReference = get-Content "C:\Temp\BeforeShopList.txt"
$strDifference = get-Content "C:\Temp\AfterShopCheckout.txt"
Compare-Object $strReference $strDifference

Note 1:  You could use the explicit parameters: -referenceObject -differenceObject and thus substitute this for the last line:
Compare-Object -referenceObject $strReference -differenceObject $strDifference

The reason that I omitted these positional parameters is that PowerShell can deduce what to compare from the sequence.

Note 2: If your script fails, then check a) That you have two files, b) They are in the folder referenced by your script.

Challenge 1: You could add the -includeEqual parameter to display all the items that you bought that were on the original list.

Expected result

InputObject  SideIndicator
————————-
Ice-Cream        =>
Cucumbers      <=
Burgers           <=

SideIndicator

I wonder if it’s me, but when I read this word quickly it says, ‘Site’ indicator and not ‘Side’ indicator.

=> Means the InputObject is present in the difference (second) file, but not in the first file.  In this scenario it means we bought stuff, which was not on the original list.

<= Present in reference (first) file, but not in the second file.  In my analogy, we forgot to buy this item on our shopping list.

== Present in both files.  Try my challenge and add the -includeEqual parameter, then you will see this double-equals underneath ‘SideIndicator’ in the output.

Guy Recommends: The Free IP Address Tracker (IPAT) IP Tracker

Calculating IP Address ranges is a black art, which many network managers solve by creating custom Excel spreadsheets.  IPAT cracks this problem of allocating IP addresses in networks in two ways:

For Mr Organized there is a nifty subnet calculator, you enter the network address and the subnet mask, then IPAT works out the usable addresses and their ranges. 

For Mr Lazy IPAT discovers and then displays the IP addresses of existing computers. Download the Free IP Address Tracker

Example 2: To Compare Two Files, with -Parameters

# Microsoft PowerShell script to research compare-Object
# Author: Guy Thomas
# Version 1.2 April 2008 tested on PowerShell v 1.0

clear-host
$strReference = get-Content "C:\Temp\list.txt"
$strDifference = get-Content "C:\Temp\checkout.txt"
compare-Object -referenceObject $strReference -differenceObject $strDifference `
-syncWindow 100 -includeEqual

Note 1:  Observe how compare-Object relies on get-Content to provide the stream of data

Note 2:  Even though it’s not necessary with a short list, I have included my favourite switch – syncWindow.  Because the resulting command would not fit on one line, added the tiny backtick ` to tell PowerShell that the command wrapped onto the next line.

Example 3: Researching Windows Services

The purpose of this example is to give you ideas for using compare-Object on a production server.

One classic computing job for compare-Object is to investigate Windows services, for example list services that have stopped.  One complication is that we need to understand and master Get-WmiObject win32_service.  The second complication is that we need to have objectives and data; for example, a list services that were running yesterday, or earlier today, but have stopped.  A solution would be to take regular snap-shots of which services are running, save the data into a file, then use compare-Object to highlight differences, i.e. services that are no longer running.

This mini-project illustrates two other factors about scripting in general and PowerShell in particular.  Firstly build-up your scripts gradually, secondly, there are always at least three ways of achieving any scripting goal, in this instance, Get-WmiObject win32_service may have enough properties and methods for you not to need compare-Object at all.

# Microsoft PowerShell script to list services
# Author: Guy Thomas
# Version 1.4 April 2008 tested on PowerShell v 1.0

clear-host
$strState = "running"
$strPath = "C:\Temp\serviceslist2.csv"
Get-WmiObject win32_service -filter "state = ‘$strState’ " |
select-object name, caption, status, startmode
Export-Csv -Path $strPath

Note 1:  Look for the file referenced by $strPath, Excel would be an ideal program to examine this csv file.

Note 2:  Research deeper with get-Member: for example:
Get-WmiObject win32_service |gm

A Big and Advanced Challenge:  I really have left a big task for you apply what you have learned in Example 1 with compare-Object, and apply the technique to Windows services.  If you accept this challenge you need to create a difference file, stop one or more services, run Example 1, but with a modified $strReference and $strDifference.

Guy Recommends: Tools4ever’s UMRAUMRA The User Management Resource Administrator

Tired of writing scripts? The User Management Resource Administrator solution by Tools4ever offers an alternative to time-consuming manual processes.

It features 100% auto provisioning, Helpdesk Delegation, Connectors to more than 130 systems/applications, Workflow Management, Self Service and many other benefits. Click on the link for more information onUMRA.

Summary of Compare Files with Compare-Object

If you have a troubleshooting scenario where you want to automate processing of two files, and come up with a list of differences; then turn to compare-Object and research its parameters.

If you like this page then please share it with your friends

 


See more Windows PowerShell examples

PowerShell Home   • Foreach loops   • PowerShell Foreach   • Foreach-Object cmdlet

Syntax   • Variables   • -whatIf   • -ErrorAction   • Windows 8 PowerShell   • Free CSV Import Tool

PowerShell Functions   • [System.Math]   • Get-Credential   • Windows PowerShell   • PowerShell 3.0

Please email me if you have a better example script.  Also please report any factual mistakes, grammatical errors or broken links, I will be happy to  correct the fault.