Search code examples
powershellcompareobject

PowerShell Compare-Object to produce change report file


I've looked at numerous examples and have made headway in producing a change report. But, I'm stuck in one area. Here's the scenario...

File 1 CSV file sample data
ID,Name,Location,Gender
1,Peter,USA,Male
2,Paul,UK,Male
3,Mary,PI,Female

File 2 CSV file sample data (No ID column)
Name,Location,Gender
Peter,USA,Female
Paul,UK,Male
Mary,USA,Female
Tom,PI,Female
Barry,CAN,Male

File 2 has changes and additions, i.e. Peter turned female, Mary moved to the US, both Tom and Barry are the new people. Change report output file contain what the changes are. Problem is, I can't figure out how to get the ID for both Peter and Mary from File 1, into my Change Report. ID is always empty Here's my code...(I hope someone can shed some light. Thanks in advance.)

$MyCSVFields = @('Name','Location','Gender')
$CompareResults = Compare-Object $RefObj $DffObj -Property $MyCSVFields -IncludeEqual
$NewOrChangedData = @()
Foreach($Row in $CompareResults)
{
    if( $Row.SideIndicator -eq "=>" )
    {                
        $TempObject = [pscustomobject][ordered] @{
            ID = $Row.ID
            Name = $Row.Name
            Location = $Row.Location
            Gender = $Row.Gender
            #Sanity check "Compare Indicator" = $Row.SideIndicator 
        }
        $NewOrChangedData += $TempObject
    }
}

Thanks to Theo for providing an understanding of how to use the Where-Object. Here is the updated code that keeps it simple for beginners and still works for us.

Foreach($Row in $CompareResults)
{
    if( $Row.SideIndicator -eq "=>" )
    {                
        $myOrgID = $RefObj | Where-Object Name -eq $Row.Name
        $TempObject = [pscustomobject][ordered] @{
            ID = $myOrgID.ID
            Name = $Row.Name
            Location = $Row.Location
            Gender = $Row.Gender
            #Sanity check "Compare Indicator" = $Row.SideIndicator 
        }
        $NewOrChangedData += $TempObject
    }
}

Solution

  • I'm also alway struggling with Compare-Object, so I hope there is a better answer than this:

    $RefObj = @'
    ID,Name,Location,Gender
    1,Peter,USA,Male
    2,Paul,UK,Male
    3,Mary,PI,Female
    '@ | ConvertFrom-Csv
    
    $DffObj = @'
    Name,Location,Gender
    Peter,USA,Female
    Paul,UK,Male
    Mary,USA,Female
    Tom,PI,Female
    Barry,CAN,Male
    '@ | ConvertFrom-Csv
    
    $MyCSVFields = @('Name','Location','Gender')
    $CompareResults = Compare-Object $RefObj $DffObj -Property $MyCSVFields -PassThru
    
    $NewOrChangedData = $CompareResults | Where-Object { $_.SideIndicator -eq '=>' } | ForEach-Object { 
        $name = $_.Name
        [PsCustomObject]@{
            ID = ($RefObj | Where-Object { $_.Name -eq $name }).ID
            Name = $name
            Location = $_.Location
            Gender = $_.Gender
            #Sanity check "Compare Indicator" = $_.SideIndicator 
        }
    }
    
    $NewOrChangedData
    

    Result:

    ID Name  Location Gender
    -- ----  -------- ------
    1  Peter USA      Female
    3  Mary  USA      Female
       Tom   PI       Female
       Barry CAN      Male