When working in PowerShell, it is common to work
with collections of objects. Most PowerShell commands generate objects, as
do many of the methods that you work with in the .NET Framework. To help
work with these object collections, PowerShell introduces the Compare-Object cmdlet. The Compare-Object cmdlet provides functionality
similar to well-known diff commands,
but with an object-oriented flavor.
To compare the output of two commands, store
the output of each command in variables, and then use the Compare-Object cmdlet to compare those
variables:
PS > notepad PS > $processes = Get-Process PS > Stop-Process -ProcessName Notepad PS > $newProcesses = Get-Process PS > Compare-Object $processes $newProcesses InputObject SideIndicator ----------- ------------- System.Diagnostics.Process (notepad) <=
The solution shows how to determine which
processes have exited between the two calls to Get-Process. The SideIndicator of <= tells us that the process was present in
the left collection ($processes) but
not in the right ($newProcesses). To
work with the actual object that was different, access the
InputObject property:
PS > $diff = @(Compare-Object $processes $newProcesses)[0] PS > $process = $diff.InputObject PS > $process.Handles 55
I think first line should be removed.
By default, the Compare-Object cmdlet
uses the comparison functionality built into most .NET objects. This
works as expected most of the time, but some times you might want to
override that comparison behavior. In the example above, for example,
you might want two processes to be considered different if their memory
usage changes. In that case, use the -Property
parameter.
PS > Compare-Object $processes $newProcesses -Property Name,WS | Sort Name Name WS SideIndicator ---- -- ------------- dwm 31358976 <= dwm 29540352 => explorer 37969920 <= explorer 38023168 => lsass 1548288 => lsass 1372160 <= notepad 5701632 <= notepad 2891776 => powershell 44281856 => powershell 44290048 <= SearchIndexer 13606912 => SearchIndexer 13619200 <= svchost 56061952 <= svchost 43982848 <= svchost 56037376 => svchost 44048384 => svchost 12193792 <= svchost 12201984 => taskeng 9220096 <= taskeng 9228288 =>
When
you use the -Property parameter, the
Compare-Object cmdlet outputs custom objects that
have only the properties you used in the comparison. If you still want
access to the original objects used in the comparison, also use the
-PassThru parameter. In that case, PowerShell instead
adds the SideIndicator property to the original
objects.
One you use --> Once you use (IMO, "When you use..." sounds better.)
If still want access --> If you still want access
If the objects you are comparing are
already in proper order (for example, the lines in a file), you can
make improve the performance of the comparison process by using the
-SyncWindow parameter. A sync window of five, for
example, only looks for differences within the surrounding five
objects.
(for example, the lines in a file,) --> (for example, the lines in a file),
For more information about the Compare-Object cmdlet, type Get-Help Compare-Object.
To determine simple differences in the content
of each file, store their content in variables, and then use the
Compare-Object cmdlet to compare
those variables:
PS > "Hello World" > c:\temp\file1.txt PS > "Hello World" > c:\temp\file2.txt PS > "More Information" >> c:\temp\file2.txt PS > $content1 = Get-Content c:\temp\file1.txt PS > $content2 = Get-Content c:\temp\file2.txt PS > Compare-Object $content1 $content2 InputObject SideIndicator ----------- ------------- More Information =>
The primary focus of the Compare-Object cmdlet is to compare two
unordered sets of objects. Although those sets of objects can be strings
(as in the content of two files), the output of Compare-Object when run against files is
usually counterintuitive due to the content losing its order.
Anoter alternative is the command: fc
When comparing large files (or files where the
order of comparison matters), you can still use traditional file
comparison tools such as diff.exe or
the WinDiff application that comes
with both the Windows Support Tools and Visual Studio.
For more information about the Compare-Object cmdlet, type Get-Help Compare-Object.
You want to determine whether any files have been modified or damaged in a set of files.
To verify the integrity of file sets, use the
Get-FileHash script provided in the section called “Program: Get the MD5 or SHA1 Hash of a File” to generate the
signatures of those files in question. Do the same for the files on a
known good system. Finally, use the Compare-Object cmdlet to compare those two
sets.
To generate the information from the files in question, use a command like:
dir C:\Windows\System32\WindowsPowerShell\v1.0 | Get-FileHash |
Export-CliXml c:\temp\PowerShellHashes.clixmlThis command gets the hash values of the files
from C:\Windows\System32\ WindowsPowerShell\v1.0,
and uses the Export-CliXml cmdlet to
store that data in a file.
Transport this file to a system with files in a known good state, and then import the data from that file.
$otherHashes = Import-CliXml c:\temp\PowerShellHashes.clixml
You can also map a network drive to the files in question and skip the export, transport, and import steps altogether:
net use x: \\lee-desk\c$\Windows\System32\WindowsPowerShell\v1.0
$otherHashes = dir x: | Get-FileHashGenerate the information from the files you know are in a good state:
$knownHashes = dir C:\Windows\System32\WindowsPowerShell\v1.0 |
Get-FileHashFinally, use the Compare-Object cmdlet to detect any
differences:
Compare-Object $otherHashes $knownHashes -Property Path,HashValue
If there are any differences, the Compare-Object cmdlet displays them in a list,
as shown in Example 22.1, “The Compare-Object cmdlet showing differences between two
files”.
Example 22.1. The Compare-Object cmdlet showing differences between two files
PS > Compare-Object $otherHashes $knownHashes -Property Path,HashValue Path HashValue SideIndicator ---- --------- ----------------------- system.management.aut... 247F291CCDA8E669FF9FA... => system.management.aut... 5A68BC5819E29B8E3648F... <= PS > Compare-Object $otherHashes $knownHashes -Property Path,HashValue | >> Select-Object Path >> Path ---- system.management.automation.dll-help.xml system.management.automation.dll-help.xml
For more information about the Compare-Object cmdlet, type Get-Help Compare-Object. For more
information about the Export-CliXml
and Import-CliXml cmdlets, type
Get-Help Export-CliXml and Get-Help
Import-CliXml, respectively.
No comments yet
Add a comment