I’ve actually had similar requirements in the past trying to create reports that showed changes (e.g. deltas) from one HR sync to another. The goal was to get who and what the current and old value was. Compare-Object tells us something is different, but not exactly what changed, only the new value. Be curious if any other experts know a better way to get this information:
function Get-ObjectDelta {
[CmdletBinding()]
param (
[psobject]$ReferenceObject,
[psobject]$DifferenceObject,
[string]$Key,
[string]$KeyDesc,
[switch]$ExcludeNewRecord
)
begin {
$exclude = @()
}
process {
$result = foreach ($prop in $ReferenceObject[0].PSObject.Properties.Name) {
if ($prop -eq $Key) {
$cmp = Compare-Object -ReferenceObject $ReferenceObject -DifferenceObject $DifferenceObject -Property $prop -PassThru |
Select @{Name='Key';Expression={$_ | Select -ExpandProperty $Key}},
@{Name='KeyDesc';Expression={$_ | Select -ExpandProperty $KeyDesc}},
@{Name='Property';Expression={$prop}},
@{Name='NewValue';Expression={'New Record'}},
@{Name='OldValue';Expression={'New Record'}}
$cmp
$exclude += $cmp.Key
}
else {
$cmp = Compare-Object -ReferenceObject $ReferenceObject -DifferenceObject $DifferenceObject -Property $prop -PassThru |
Select @{Name='Key';Expression={$_ | Select -ExpandProperty $Key}},
@{Name='KeyDesc';Expression={$_ | Select -ExpandProperty $KeyDesc}},
@{Name='Property';Expression={$prop}},
@{Name='NewValue';Expression={$_ | Select -ExpandProperty $prop}},
@{Name='OldValue';Expression={$currentKey=$_.$Key;$old | Where{$_.$Key -eq $currentKey} | Select -ExpandProperty $prop}}
if ($ExcludeNewRecord) {
$cmp | Where{$exclude -notcontains $_.Key}
}
else {
$cmp
}
}
}
}
end {
$result
}
}
$old = @"
EmployeeId,Name,Department,Title,CostCenter
434242,Joe Smith,Marketing,Analyst I,50000003421
434245,Julie Johnson,Legal,Director,50000004444
434248,Terry Tripp,Security,Manager,50000001234
"@ | ConvertFrom-CSV
$new = @"
EmployeeId,Name,Department,Title,CostCenter
434242,Joe Smith,Marketing,Analyst I,50000003421
434245,Julie Johnson,Information,Director,50000004141
434248,Terry Tripp,Security,Manager,50000001234
434260,Sal Goodman,Legal,Analyst II,50000004444
"@ | ConvertFrom-CSV
$params = @{
ReferenceObject = $old
DifferenceObject = $new
Key = 'EmployeeId'
KeyDesc = 'Name'
ExcludeNewRecord = $true
}
Get-ObjectDelta @params
Output:
Key : 434260
KeyDesc : Sal Goodman
Property : EmployeeId
NewValue : New Record
OldValue : New Record
Key : 434245
KeyDesc : Julie Johnson
Property : Department
NewValue : Information
OldValue : Legal
Key : 434245
KeyDesc : Julie Johnson
Property : CostCenter
NewValue : 50000004141
OldValue : 50000004444
I would create PowerBi reports from this data, which would also include a Date to see what happened during each sync. The function could be made more efficient by possibly running a Compare-Object to get only changed rows and then process the properties, but curious how long this would take against 1000 rows * 20 properties. Another option is to use SQL as well: