Makes sure you run the script provided with the event to get the right folders. The script randomly removes 1 file from each folder – sneaky.
After last nights head scratching this one is much simpler. It’s solvable with one line of PowerShell.
For this one we have a data folder and a back up folder we need to compare.
Requirements:
- Content of backup folder is same as data folder
- Only compare file names
- Show files in one folder that don’t exist in other
- Return file information objects as result of comparison
- Don’t need complicated script
- Unnecessary complexity costs points
- Extra points for native PowerShell cmdlets and code simplicity
We need to deal with file names – so that implies Get-ChildItem. We can see the contents of the files:
Get-ChildItem -Path c:\1
Get-ChildItem -Path c:\2
Do we have anything to do a compare?
Get-Command *compare*
shows we have compare-object.
If you haven’t seen this before – read the help.
In fact as a general rule read the help for all cmdlets before using in the games just to make sure you understand them and you’ve picked up on all the extras that might help you.
PS> get-help Compare-Object
SYNOPSIS
Compares two sets of objects.
SYNTAX
Compare-Object [-ReferenceObject] <PSObject[]> [-DifferenceObject] <PSObject[]>
[-CaseSensitive] [-Culture <string> ] [-ExcludeDifferent] [-IncludeEqual] [-PassThru]
[-Property <Object[]>] [-SyncWindow <int>] [<CommonParameters>]
DESCRIPTION
The Compare-Object cmdlet compares two sets of objects. One set of objects is the Reference set,
and the other set is the Difference set.
The result of the comparison indicates whether a property value appeared only in the object from
the Reference set (indicated by the <= symbol), only in the object from the Difference set
(indicated by the => symbol) or, if the IncludeEqual parameter is specified, in both objects
(indicated by the == symbol).
This means we need to treat the folder contents as objects. PowerShell has a very clever trick we can use here. We put the
Get-ChildItem -Path c:\1
Get-ChildItem -Path c:\2
in parentheses which tells PowerShell to treat them as objects and we can use these directly as input to compare-object.
PS> Compare-Object -ReferenceObject (Get-ChildItem -Path c:\1) -DifferenceObject (Get-ChildItem -Path c:\2)
InputObject SideIndicator
———– ————-
13.txt =>
10.txt <=
That should make sense now you can see what I mean. The alternative would be to do this
PS> $list1 = Get-ChildItem -Path c:\1
PS> $list2 = Get-ChildItem -Path c:\2
PS> Compare-Object -ReferenceObject $list1 -DifferenceObject $list2
InputObject SideIndicator
———– ————-
13.txt =>
10.txt <=
which involves more typing and depending on how you define complexity is more complex.
We can do the compare but we need to restrict the comparison to file names – so we need the –Property parameter. This is why you need to read the help file.
Compare-Object -ReferenceObject (Get-ChildItem -Path c:\1) -DifferenceObject (Get-ChildItem -Path c:\2) -Property Name
This still produces the output above and we were told to output file objects. Once more into the help file and we find –Passthru which “Passes the objects that differed to the pipeline. By default, this cmdlet does not generate any output.”
PS> Compare-Object -ReferenceObject (Get-ChildItem -Path c:\1) -DifferenceObject (Get-ChildItem -Path c:\2) -Property Name -PassThru
Directory: C:\2
Mode LastWriteTime Length Name
—- ————- —— —-
-a— 14/04/2012 15:54 0 13.txt
Directory: C:\1
Mode LastWriteTime Length Name
—- ————- —— —-
-a— 14/04/2012 15:54 0 10.txt
That solves the problem and is as simple as it gets. Oh you want aliases as well.
compare -R (ls c:\1) -Di (ls c:\2) -Pr Name –Pa
And that is why I don’t like aliases because it is no where near as obvious what I am doing.