Ян давид наркевич разработчик

Set-StrictMode -Version 3.0

$ErrorActionPreference = ‘Stop’

# Set-PSDebug -Trace 1

        (Resolve-Path -Path $folderPath -ErrorAction Stop).Path + ‘\’

            -Path $folderPath `

        -ReferenceObject $sourceFiles `

        -DifferenceObject $destinationFiles `

    $exitCode = $exitCodeError

        “Exception Message: $($errorRecord.Exception.Message), ” + `


This particular example compares the differences between each of the rows in the text files named teams1.txt and teams2.txt.

Ян давид наркевич разработчик

And suppose we have another file named teams2.txt that contains the names of some more basketball teams:

Ян давид наркевич разработчик

Suppose that we would like to compare these two text files to identify the similarities and differences between them.

PowerShell compare two files

The output displays which values exist in only one of the text files.

The symbol => indicates that a particular value only exists in the second file.

Conversely, the symbol <= indicates that a particular value only exists in the first file.

Ян давид наркевич разработчик

We can see that there are 6 total values that are different between the two files.

PowerShell: How to Compare Two Arrays
PowerShell: How to Compare Dates
PowerShell: How to List Files in Directory by Date

So every week I get a list of MAC’s that show up that are not known. With the list I need to research what they are and there purpose. However some of these MAC’s have been resolved from previous weeks. I currently have a save sheet of all the different MAC’s from previous weeks and there reason for being on the network. When I get a new list I compare the two side by side. Any MAC’s that do not match I add them to the saved list and investigate. To make this easier I am looking for a way to use PowerShell to compare the two list and spit out the differences. To get script going and to work from I made this bellow. However when running it I get the entire list of MAC’s from the New list. How do I go about having the new list compare objects on the old list and list the differences?

EDIT:: I Forgot to mention for the differences. I just don’t want what is different between both list. I am only looking for what is different in the new list. This way I can take these and append them to the old list.

3 Important Parameters:

The ReferenceObject is the baseline.

The DifferenceObject is what you are looking for differences in.

This is the property of the object that you are comparing. Can be a comma-seperated list?

Indicates that the property is present only on the ReferenceObject (Left Side).

Indicates that the property is present only on the DifferenceObject (Right Side).

Compares two files and displays the differences using the File Compare command in CMD.

fc C:\path\to\file1.txt C:\path\to\file2.txt

Compares the contents of two files or sets of files byte-by-byte, using the Comp command.

comp C:\path\to\file1.txt C:\path\to\file2.txt

Compares two files and shows differences using PowerShell. This command reads each file’s content and then compares the objects.

Checks if two files are identical, returning True or False, using PowerShell.

An alias in PowerShell for Compare-Object, used to compare file contents similar to the Unix/Linux command.

Note: as an alias may not be available in all PowerShell environments by default.

Example: Comparing two text Files

Example: Comparing the Process List of two computers:

Collect the baseline computer’s process list:

Move it to the other computer to compare:

PowerShell Compare-Object

Comparing data sets and identifying differences is common in programming and scripting. When working with objects and values in PowerShell, you’ll often need to find out what’s changed between two sets of data. That’s where the powerful Compare-Object cmdlet comes in.

The Compare-Object cmdlet provides a quick and easy way to compare two sets of objects and reveal the differences. In this in-depth guide, I will take you through everything you need to know about mastering PowerShell’s Compare-Object for efficient data analysis.

In this post, I’ll provide a comprehensive guide on using Compare-Object in PowerShell. We’ll cover:

  • What Compare-Object is used for and when to use it
  • Comparing two sets of objects/data and outputting the differences
  • Using Compare-Object to find matching items between two objects
  • Comparing based on specific object properties rather than the full object
  • Comparing data from files, CSVs, and more
  • Filtering and formatting Compare-Object output for reports

You’ll learn best practices for leveraging Compare-Object to efficiently compare PowerShell objects and reveal meaningful differences. Whether you’re comparing system settings, file folders, auditing changes, or analyzing data sets, this post will help you master Compare-Object. By the end, you’ll be able to harness the power of Compare-Object to isolate important changes between objects in your PowerShell scripts and workflows. Ready to start comparing? Let’s go!

Introduction to PowerShell’s Compare-Object

PowerShell’s Compare-Object is a cmdlet that allows you to compare two sets of data and identify the differences between them. This can be particularly useful when you are working with arrays, lists, or object arrays. By using Compare-Object, you can easily find the missing, added, or changed items between two sets of data.

Understanding the Syntax and Parameters of Compare-Object

Compare-Object 
[-ReferenceObject] <Object[]> 
[-DifferenceObject] <Object[]> 
[-Property <String[]>] 
[-IncludeEqual]
[-ExcludeDifferent] 
[-PassThru] 
[-Culture <String>] 
[-SyncWindow <Int32>] 
[-CaseSensitive] 
[<CommonParameters>]

Here is a brief explanation of each parameter:

:/>  Как перемещаться по каталогам в cmd
ParameterDescription
-ReferenceObjectSpecifies an array of reference objects. It’s the main object set you want to compare against. Typically, this is the “known” or “standard” data set.
-DifferenceObjectSpecifies an array of objects to compare with the reference objects. Typically, this is the “new” or “variable” data set.
-PropertySpecifies the properties to compare. If this parameter isn’t specified, the cmdlet compares the objects themselves.
-CaseSensitiveMakes the comparison case-sensitive. By default, comparisons are case-insensitive.
-CultureSpecifies the culture to use in the comparison. This is important for string comparisons where characters might be treated differently across cultures.
-ExcludeDifferentExcludes from the output objects that are different. It shows only equal objects.
-IncludeEqualShows objects that are equal. By default, only differences are shown.
-PassThruPasses the output object through the pipeline.
-SyncWindowSpecifies how many adjacent objects surrounding a differing object to include in a comparison. This parameter is important when comparing objects that might be slightly out of order but are still considered a match.

I once faced a similar problem. This is the method I ended up with:

function Assert-FolderMatches {
    <#
    .SYNOPSIS
        Assert folder matches reference
    .DESCRIPTION
        Recursively compare folders ensuring that all files and folders have been copied correctly.
        If the file length doesn't match it will also raise an error.
    .PARAMETER Path
        Path to compare.
    .PARAMETER ReferencePath
        Path to compare with (the source folder for how it should look like).
    .PARAMETER AllowNewFiles
        Allow files to be present in Path which are not present in ReferencePath (like log files).
    #>
    Param(
        [Parameter(Mandatory = $true)]
        [string] $Path,

        [Parameter(Mandatory = $true)]
        [string] $ReferencePath,

        [Parameter()]
        [switch] $AllowNewFiles
    )

    $Path = Resolve-Path $Path
    $ReferencePath = Resolve-Path $ReferencePath

    # Identify all files and folders.
    function Get-ItemsForFolder($FolderPath) {
        Get-ChildItem -Path $FolderPath -Recurse | ForEach-Object { 
            $relativePath = $_.FullName.Replace($FolderPath, "")

            if ($relativePath.StartsWith('\') -or $relativePath.StartsWith('/')) {
                $relativePath = $relativePath.Substring(1)
            }

            if ($_ -is [System.IO.DirectoryInfo]) {
                [pscustomobject] @{
                    'RelativePath' = $relativePath;
                    'Length'       = $null;
                }
            } else {
                [pscustomobject] @{
                    'RelativePath' = $relativePath;
                    'Length'       = $_.Length;
                }
            }
        }
    }

    $files = Get-ItemsForFolder $Path
    $matchFiles = Get-ItemsForFolder $ReferencePath

    # Compare items from both sides.
    $diff = Compare-Object -ReferenceObject $matchFiles `
        -DifferenceObject $files `
        -Property RelativePath,Length
    
    # Filter out additions from 'Path' side if requested.
    if ($AllowNewFiles) {
        $diff = $diff | Where-Object { $_.SideIndicator -ne '=>' }
    }

    return $diff
}

Not the most simple solution, maybe someone has a more elegant way to do this. Essentially I’m using relative paths to compare, instead of just the file name.

And here’s an example output. So you can see that “b.txt” exists in both target and source folder, but in a different location and it’s raised as a difference:

$> Assert-FolderMatches -ReferencePath C:\Temp\a -Path C:\Temp\b 

RelativePath Length SideIndicator
------------ ------ -------------
f2                  =>
f2\b.txt     0      =>
f1                  <=
f1\b.txt     0      <=

Just as a note, I’m not comparing actual file content. I tried to do this with hashing, but it was too slow for my use case. So I ended up just comparing file size, which seems a reasonable compromise for copying to me, unless you’re really worried about file corruption in some way.

Comparing Arrays with Compare-Object

powershell compare

One of the most common ways of using Compare-Object is to compare two arrays. An array is a collection of items that are stored in a specific order. PowerShell’s Compare-Object can compare two arrays and identify the items that are missing, added, or changed.

To compare two arrays using Compare-Object, you need to specify the arrays as the ReferenceObject and DifferenceObject parameters. To grasp the fundamentals, let’s begin with a basic compare-object PowerShell example:

$Array1 = @(1, 2, 3, 4, 5)
$Array2 = @(1, 2, 4, 5, 6)

Compare-Object -ReferenceObject $Array1 -DifferenceObject $Array2

The above code will compare two arrays and return the differences. It’s a straightforward use case that showcases the capability of PowerShell Compare functionalities. Here is the output:

InputObject SideIndicator
----------- -------------
6           =>
3           <=

In this example, the SideIndicator column indicates that the number 3 is in the ReferenceObject array (indicated by the <= symbol) and not in the DifferenceObject array, and the number 6 is in the DifferenceObject array (indicated by the => symbol) and not in the ReferenceObject array.

Compare-Object checks the objects in the first set against the second set to identify:

  • Objects only in set 1 (additions)
  • Objects only in set 2 (removals)
  • Objects in both, but with differing properties (changes)

This approach makes it easy to see what’s been added, removed, or modified between any two object collections.

Comparing arrays is a common task, especially when you want to find out which elements are present in one array but not in another. Consider the example below:

$FirstArray = "apple", "banana", "cherry"
$SecondArray = "banana", "cherry", "date"

#Compare Arrays
Compare-Object $FirstArray $SecondArray

In this PowerShell to compare two arrays example, the script will return “apple” from the first array and “date” from the second as differences.

InputObject SideIndicator
----------- -------------
date        =>           
apple       <=           

We can create a function that compares given arrays and returns the result of the comparison.

Function Check-ObjectsEqual {
    param (
        [Parameter(Mandatory=$true)]
        $Object1,

        [Parameter(Mandatory=$true)]
        $Object2
    )

    $ComparisonResult = Compare-Object -ReferenceObject $Object1 -DifferenceObject $Object2

    # If there are no differences, return $true, otherwise return $false
    return ($null -eq $comparisonResult)
}

# Example Usage:

$Array1 = 1,2,3,4,5
$Array2 = 1,2,3,4,5,6

if (Check-ObjectsEqual -Object1 $Array1 -Object2 $Array2) {
    Write-Output "The objects are equal."
} else {
    Write-Output "The objects are not equal."
}
Function Check-Objects {
    param(
        [Parameter(Mandatory = $true)]
        $Object1,
        [Parameter(Mandatory = $false)]
        $Object2
    )

    return !(Compare-Object $Object1.PSObject.Properties $Object2.PSObject.Properties)
}

$PSCustomObj1 = [PSCustomObject]@{
    Name = "John"
    Age = 20
    City = "Anytown"
}

$PSCustomObj2 = [PSCustomObject]@{
    Name = "John"
    Age = 30
    City = "Anytown"
}

Check-Objects $PSCustomObj1 $PSCustomObj2

Compare and return only matching Items

To diff two text files in PowerShell, you can use the Compare-Object cmdlet. Let’s walk through examples of comparing two sets of objects, to only return matches:

#Get Server Names from text files
$Servers1 = Get-Content C:\Data\Servers1.txt
$Servers2 = Get-Content C:\Data\Servers2.txt

#Compare two object arrays and list the uniform elements
Compare-Object $Servers1 $Servers2 -IncludeEqual -ExcludeDifferent | Select -ExpandProperty InputObject

This prints matched objects in both sets, excluding differences.

:/>  Equalizer APO - Browse Files at

Comparing Lists with Compare-Object

Another common way of using Compare-Object is to compare two lists. A list is similar to an array, but it is not stored in a specific order. PowerShell’s Compare-Object can compare two lists and identify the items that are missing, added, or changed.

Just like arrays, you can compare two lists:

# Create Lists
$EUServers = [System.Collections.Generic.List[string]]("EUS-WEB-01", "APP-TOK-01", "EUS-API-03")
$USServers = [System.Collections.Generic.List[string]]("ES-MAD-003", "APP-TOK-01", "US-CHI-001")

# Compare Lists
Compare-Object $EUServers $USServers

To compare two lists using Compare-Object, you need to specify the lists as the ReferenceObject and DifferenceObject parameters. Here is another example:

$List1 = 1, 2, 3, 4, 5
$List2 = 1, 2, 4, 5, 6

Compare-Object $List1 $List2
InputObject SideIndicator
----------- -------------
3           <=           
6           =>      

As you can see, the output is the same as when comparing arrays.

Using the SideIndicator Parameter in Compare-Object

The SideIndicator parameter in Compare-Object is a powerful tool for filtering out irrelevant items from your analysis. The SideIndicator column indicates whether an item is in the ReferenceObject array, the DifferenceObject array, or both.

When you get the result from Compare-Object, you’ll see a SideIndicator property. Here’s what they mean:

  • =>: The object is present in the DifferenceObject (or second input).
  • <=: The object is present in the ReferenceObject (or first input).

Knowing this helps in understanding where the difference lies, making your PowerShell compare-object sideindicator knowledge essential.

Here is an example:

$Array1 = 1, 2, 3, 4, 5
$Array2 = 1, 2, 4, 5, 6

Compare-Object $Array1 $Array2 -IncludeEqual | Where-Object { $_.SideIndicator -eq '==' }
InputObject SideIndicator
----------- -------------
1           ==          
2           ==          
4           ==          
5           ==          

In this example, we are comparing two arrays and including the items that are the same in both arrays using the IncludeEqual parameter. We are then using the Where-Object cmdlet to filter out the items that are not relevant to our analysis by selecting only the items that have a SideIndicator value of ‘==’.

Comparing Multiple Properties with Compare-Object

Sometimes, you may need to compare two sets of data based on multiple properties. PowerShell’s Compare-Object allows you to do this by specifying multiple properties using the Property parameter.

Here is an example:

$ObjectArray1 = @( 
    [pscustomobject] @{ Name = 'John'; Age = 30; City = 'New York' },
    [pscustomobject] @{ Name = 'Jane'; Age = 25; City = 'Los Angeles' },
    [pscustomobject] @{ Name = 'Bob'; Age = 40; City = 'Chicago' }
)

$ObjectArray2 = @( 
    [pscustomobject] @{ Name = 'John'; Age = 30; City = 'New York' },
    [pscustomobject] @{ Name = 'Jane'; Age = 26; City = 'Los Angeles' },
    [pscustomobject] @{ Name = 'Alice'; Age = 35; City = 'Chicago' }
)

Compare-Object $ObjectArray1 $ObjectArray2 -Property Name, Age, City
Name  Age City        SideIndicator
----  --- ----        -------------
Jane   26 Los Angeles =>           
Alice  35 Chicago     =>           
Jane   25 Los Angeles <=           
Bob    40 Chicago     <=           

In this example, we are comparing two object arrays based on the Name, Age, and City properties. The SideIndicator column indicates that the object with the name Jane, age 25, and city Los Angeles is in the ReferenceObject array and not in the DifferenceObject array, the object with the name Jane, age 26, and city Los Angeles is in the DifferenceObject array and not in the ReferenceObject array, and so on.

Advanced Techniques for Using Compare-Object in Data Analysis

Comparing Nested Objects

You can use Compare-Object to compare objects that contain nested objects. To do this, you need to specify the nested properties using dot notation. Here is an example:

$Object1 = [pscustomobject] @{
    Name = 'John'
    Address = [pscustomobject] @{
        Street = '123 Main St'
        City = 'New York'
    }
}

$Object2 = [pscustomobject] @{
    Name = 'John'
    Address = [pscustomobject] @{
        Street = '456 Main St'
        City = 'New York'
    }
}

Compare-Object $Object1 $Object2 -Property Name, {$_.Address.Street}
Name Address.Street SideIndicator
---- -------------- -------------
John 123 Main St    <=           
John 456 Main St    =>           

In this example, we are comparing two objects that contain a nested Address object. We are comparing the objects based on the Name and Address.Street properties.

Comparing Objects with Different Properties

You can use Compare-Object to compare objects that have different properties. To do this, you need to use the Property parameter to specify the common properties that will be used for comparison. Here is an example:

$user1 = [PSCustomObject]@{Name="Alice"; Age=25; City = "New York"}
$user2 = [PSCustomObject]@{Name="Bob"; Age=26; Country = "United States" }

#Compare objects based on specific properties
Compare-Object -ReferenceObject $User1 -DifferenceObject $User2 -Property Name, Age
Name  Age SideIndicator
----  --- -------------
Bob    26 =>           
Alice  25 <=         

In this example, we are comparing two objects that have different properties. We are comparing the objects based on the common Name property.

Comparing Objects with Different Property Names

You can use Compare-Object to compare objects that have different property names. To do this, you need to use the Property parameter to map the properties to a common name. Here is an example:

:/>  Фальшивые ошибки chrome используются для запуска power shell скриптов

Imagine you’ve received data from two different systems about employees. One system exports the employee’s full name as “FullName”, and the other exports the employee’s name as “Name”. You want to compare these two lists to see if they contain the same names.

$SystemAData = @(
    [PSCustomObject]@{FullName='Alice Smith'},
    [PSCustomObject]@{FullName='Bob Jones'},
    [PSCustomObject]@{FullName='Charlie Brown'}
)

$SystemBData = @(
    [PSCustomObject]@{Name='Alice Smith'},
    [PSCustomObject]@{Name='Charlie Brown'},
    [PSCustomObject]@{Name='David Williams'}
)

Compare-Object -ReferenceObject $SystemAData.FullName -DifferenceObject $SystemBData.Name
InputObject    SideIndicator
-----------    -------------
David Williams =>           
Bob Jones      <=      

In this example, we compare two objects with different property names. We use the Property parameter to map the Name property in the first object to the FirstName property in the second object.

Excluding Common Differing Properties

# Get files from both directories
$Folder1Files = Get-ChildItem -Path "C:\Source" -File | Select-Object Name, Length
$Folder2Files = Get-ChildItem -Path "C:\Destination" -File | Select-Object Name, Length

# Compare the files
$ComparisonResult = Compare-Object -ReferenceObject $Folder1Files -DifferenceObject $Folder2Files -Property Name, Length

# Output the comparison results
$comparisonResult

Now, last write timestamp differences are ignored in the comparison.

Formatting and Filtering Output

The raw Compare-Object output can be hard to analyze. Use formatting and filtering to highlight key differences:

Compare-Object $Object1 $Object2 | Format-Table -Property Name,SideIndicator

This formats a table view of just the Name, and SideIndicator. You can also filter for specific differences:

Compare-Object $Folder1Files $Folder2Files -Property Name | Where-Object SideIndicator -eq "=>"

Now, it only shows objects unique to the second set. Taking the time to properly format and filter the output pays dividends when trying to pinpoint important changes.

Compare CSV File Contents using Compare-Object Cmdlet

The Compare-Object cmdlet is especially useful when you want to compare the contents of two CSV files to identify differences. Below is how to accomplish this using PowerShell:

# Import CSV files
$File1Contents = Import-Csv -Path "C:\Data\ServerList1.csv"
$File2Contents = Import-Csv -Path "C:\Data\ServerList2.csv"

# Compare the CSV files
$ComparisonResult = Compare-Object -ReferenceObject $File1Contents -DifferenceObject $File2Contents -Property ServerName

# Output the comparison results
$comparisonResult

The above example assumes that both CSV files have the header “ServerName” for property value. If the headers (column names) are different, or if you want to compare only specific columns, you’d need to modify the script accordingly.

Using Compare-Object to Compare Object Arrays

An object array is an array where each item is an object with properties. PowerShell’s Compare-Object can compare two object arrays and identify the objects that are missing, added, or changed.

To compare two object arrays using Compare-Object, you need to specify the arrays as the ReferenceObject and DifferenceObject parameters. You also need to specify the properties for comparison using the Property parameter. Here is an example:

$ObjectArray1 = @( 
    [pscustomobject] @{ Name = 'John'; Age = 30 },
    [pscustomobject] @{ Name = 'Jane'; Age = 25 },
    [pscustomobject] @{ Name = 'Bob'; Age = 40 }
)

$ObjectArray2 = @( 
    [pscustomobject] @{ Name = 'John'; Age = 30 },
    [pscustomobject] @{ Name = 'Jane'; Age = 26 },
    [pscustomobject] @{ Name = 'Alice'; Age = 35 }
)

Compare-Object $ObjectArray1 $ObjectArray2 -Property Name, Age
Name Age SideIndicator
---- --- -------------
Jane   25   <=           
Jane   26   =>           
Bob    40   <=           
Alice  35   =>

In this example, we are comparing two object arrays based on the Name and Age properties. The SideIndicator column indicates that the object with the name Jane and age 25 is in the ReferenceObject array and not in the DifferenceObject array, the object with the name Jane and age 26 is in the DifferenceObject array and not in the ReferenceObject array, and so on.

Please note that when you compare objects, You must use the “Property” parameter. Because the Compare-Object just compares the string representation of the object properties.

Here is a real-world example to compare processes on the machine: Let’s assume you’re trying to compare processes between two different time points on the same machine.

# Step 1: Capture processes at T1
$T1Processes = Get-Process | Select-Object -ExpandProperty ProcessName

#Start Notepad
Start-Process Notepad

# Step 2: Capture processes at T2 (let's assume a new process "notepad" has started by now)
$T2Processes = Get-Process | Select-Object -ExpandProperty ProcessName

# Step 3: Compare the two lists
$ComparisonResult = Compare-Object -ReferenceObject $T1Processes -DifferenceObject $T2Processes

# Display the differences
$ComparisonResult

Compare directory contents

One of the great things about Compare-Object is it works across many object types. Compare directory contents:

Compare-Object (Get-ChildItem C:\Source) (Get-ChildItem C:\Destination)

This reveals differences between files and folders across the directories. You can compare all files in both libraries using:

$SourceFiles = Get-ChildItem -Path "C:\Source" -Recurse
$DestinationFiles = Get-ChildItem -Path "C:\Destination" -Recurse
Compare-Object $SourceFiles $DestinationFiles -Property Name, Length

Key Takeaways for Efficient Data Comparison with Compare-Object

Here are some best practices for using Compare-Object for efficient data analysis:

  • Use the SideIndicator parameter to filter out the items that are not relevant to your analysis.
  • Use the Property parameter to specify the properties that will be used for comparison.
  • Use the -IncludeEqual and -ExcludeDifferent parameters to control the output of Compare-Object.
  • Use the -PassThru parameter to return the objects that are being compared.
  • Use the -Culture parameter to specify the culture that is used for comparison.
  • Use the -CaseSensitive parameter to specify whether the comparison is case-sensitive or not.

Conclusion and Next Steps

Compare-Object enables you to efficiently compare data from files, APIs, directories, databases, and more. It’s invaluable for auditing changes, analyzing data, and revealing meaningful differences between objects. With just one line, you can easily identify differences, changes, and commonalities between two collections of objects.

In this in-depth guide, we have covered everything you need to know about mastering PowerShell’s Compare-Object for efficient data analysis. We started by introducing Compare-Object and its syntax and parameters. We then covered how to compare arrays, lists, and object arrays, as well as how to compare objects based on multiple properties. Finally, we covered some advanced techniques for using Compare-Object in data analysis, as well as some key takeaways and best practices for efficient data analysis.

Hopefully, these will give you even more help to leverage the power of PowerShell for all your comparison needs!

Оставьте комментарий