Public/Get-PegasusSyncOperations.ps1
function Get-PegasusSyncOperations { [CmdletBinding(SupportsShouldProcess = $true)] Param ( [Parameter(Mandatory = $false, Position = 0)] [Switch] $Delta ) Process { $ExistingPersons = Get-PegasusConnectorPersons -ConnectorId $Script:SyncSessionConnectorId $ExistingPersonsMap = ($ExistingPersons | Where-Object { $_.($Script:SyncSessionPersonJoinAttribute) } | Group-Object -Property $Script:SyncSessionPersonJoinAttribute -AsHashTable) ?? @{} Write-Verbose "Found $(($ExistingPersons | Measure-object).Count) persons in the connector" $ExistingPositions = Get-PegasusConnectorPositions -ConnectorId $Script:SyncSessionConnectorId $ExistingPositionsMap = ($ExistingPositions | Group-Object -Property "sourceid" -AsHashTable) ?? @{} Write-Verbose "Found $(($ExistingPositions | Measure-object).Count) positions in the connector" $ExistingGenericData = Get-PegasusConnectorGenericData -ConnectorId $Script:SyncSessionConnectorId $ExistingGenericDataMap = ($ExistingGenericData | Group-Object -Property "sourceid" -AsHashTable) ?? @{} Write-Verbose "Found $(($ExistingGenericData | Measure-object).Count) generic data in the connector" $ExistingOrgUnits = Get-PegasusConnectorOrgUnits -ConnectorId $Script:SyncSessionConnectorId $ExistingOrgUnitsMap = ($ExistingOrgUnits | Group-Object -Property "sourceid" -AsHashTable) ?? @{} Write-Verbose "Found $(($ExistingOrgUnits | Measure-object).Count) org units in the connector" #region Sync persons if ($Script:SyncSessionObjects["person"]) { Write-Verbose "Syncing persons" $inc = 0 $totalcount = $Script:SyncSessionObjects["person"].Count $Script:SyncSessionObjects["person"].GetEnumerator() | ForEach-Object { $inc += 1 $Person = $_ # $Person = $Script:SyncSessionObjects["person"].GetEnumerator() | Foreach-Object { $_ } | get-random -count 1 Write-Debug "Processing person $($Person.Key) ($inc / $totalcount)" $ExistingPerson = $ExistingPersonsMap[$Person.Key] $Body = @{ ssn = $Person.Value.ssn anchor = $Person.Value.anchor displayname = $Person.Value.displayname firstname = $Person.Value.firstname lastname = $Person.Value.lastname mobile = $Person.Value.mobile customfields = $Person.Value.customfields } if (-not $ExistingPerson) { Write-Verbose "Person $($Person.Key) will be updated ($inc / $totalcount) - $($Body.firstname) $($Body.lastname)" $ExistingPersonsMap[$Person.Key] = New-PegasusSyncOperation -Method Post -Endpoint "/connectors/$($Script:SyncSessionConnectorId)/persons" -Body $Body -Type "Create person" $ExistingPersonsMap[$Person.Key] } else { $difference = New-Object System.Collections.ArrayList # Determine differences between existing and new person $Body.keys | where-object { $_ -notin "customfields" } | where-object { $Body[$_] -ne $ExistingPerson.$_ } | ForEach-Object { $difference.Add($_) } | Out-Null $Left = $Body.customfields ?? @{} $Right = $ExistingPerson.customfields ?? @{} @($Left.Keys; $Right.Keys) | Sort-Object -Unique | ForEach-Object { $key = $_ if ($Left.$key -cne $Right.$key) { $difference.Add("customfields/$key") | Out-Null } } if ($difference.Count -gt 0) { Write-Verbose "Person $($Person.Key) will be updated ($inc / $totalcount) - $($Body.firstname) $($Body.lastname) with diff in these attributes: $($difference -join ", ")" New-PegasusSyncOperation -Method PATCH -Endpoint "/connectors/$($Script:SyncSessionConnectorId)/persons/$($ExistingPerson.id)" -Body $Body -Type "Update person" -Old $ExistingPerson -Difference $difference } else { Write-Debug "Person $($Person.Key) ($inc / $totalcount) - $($Body.firstname) $($Body.lastname) is up to date" } } } } else { Write-Verbose "No persons to sync" } #endregion #region Sync org units if ($Script:SyncSessionObjects["orgunit"]) { Write-Verbose "Syncing org units" $inc = 0 $totalcount = $Script:SyncSessionObjects["orgunit"].Count $Script:SyncSessionObjects["orgunit"].GetEnumerator() | ForEach-Object { $inc += 1 $OrgUnit = $_ # $OrgUnit = $Script:SyncSessionObjects["orgunits"].GetEnumerator() | Foreach-Object { $_ } | get-random -count 1 Write-Debug "Processing org unit $($OrgUnit.Key) ($inc / $totalcount)" $ExistingOrgUnit = $ExistingOrgUnitsMap[$OrgUnit.Key] $Body = @{ sourceid = $OrgUnit.Value.sourceid parent = $null managers = New-Object System.Collections.ArrayList longname = $OrgUnit.Value.longname shortname = $OrgUnit.Value.shortname displayname = $OrgUnit.Value.displayname customfields = $OrgUnit.Value.customfields } if ($OrgUnit.Value.parent) { $Body.parent = $ExistingOrgUnitsMap[$OrgUnit.Value.parent].id if (!$Body.parent) { Write-Warning "Parent org unit $($OrgUnit.Value.parent) does not exist" } else { Write-Debug "Parent org unit $($OrgUnit.Value.parent) maps to $($Body.parent)" } } if ($OrgUnit.Value.managers) { $OrgUnit.Value.managers | ForEach-Object { $manager = $ExistingPersonsMap[$_] if ($manager.id) { $Body.managers.Add($manager.id) | Out-Null } else { Write-Warning "Manager person $($_) does not exist" } } } $Body["deputies"] = New-Object System.Collections.ArrayList if ($OrgUnit.Value.deputies) { $OrgUnit.Value.deputies | ForEach-Object { $deputy = $ExistingPersonsMap[$_] if ($deputy.id) { $Body.deputies.Add($deputy.id) | Out-Null } else { Write-Warning "Deputy person $($_) does not exist" } } } else { if ($ExistingOrgUnit.deputies) { $ExistingOrgUnit.deputies | Foreach-Object { $Body["deputies"].Add($_) | Out-Null } } } $Body["roleassignments"] = $ExistingOrgUnit.roleassignments if (-not $ExistingOrgUnit) { Write-Verbose "Orgunit $($OrgUnit.Key) will be created ($inc / $totalcount) - $($Body.displayname)" $ExistingOrgUnitsMap[$OrgUnit.Key] = New-PegasusSyncOperation -Method Post -Endpoint "/connectors/$($Script:SyncSessionConnectorId)/orgunits" -Body $Body -Type "Create orgunit" $ExistingOrgUnitsMap[$OrgUnit.Key] } else { $difference = New-Object System.Collections.ArrayList # Determine differences between existing and new position $Body.keys | where-object { $_ -notin "customfields", "managers", "deputies" } | where-object { $Body[$_] -cne $ExistingOrgUnit.$_ } | ForEach-Object { $difference.Add($_) } | Out-Null # Check managers field if ((Compare-Object @($Body.managers ?? @()) @($ExistingOrgUnit.managers ?? @()))) { $difference.Add("managers") | Out-Null } # Check deputies field if ((Compare-Object @($Body.deputies ?? @()) @($ExistingOrgUnit.deputies ?? @()))) { $difference.Add("deputies") | Out-Null } $Left = $Body.customfields ?? @{} $Right = $ExistingOrgUnit.customfields ?? @{} @($Left.Keys; $Right.Keys) | Sort-Object -Unique | ForEach-Object { $key = $_ if ($Left.$key -cne $Right.$key) { $difference.Add("customfields/$key") | Out-Null } } if ($difference.Count -gt 0) { Write-Verbose "Orgunit $($OrgUnit.Key) will be updated ($inc / $totalcount) with diff in these attributes: $($difference -join ", ")" Write-Debug "Detailed orgunit change: $($Body | ConvertTo-Json -Depth 10 -Compress) VS $($ExistingOrgUnit | ConvertTo-Json -Depth 10 -Compress)" New-PegasusSyncOperation -Method PATCH -Endpoint "/connectors/$($Script:SyncSessionConnectorId)/orgunits/$($ExistingOrgUnit.id)" -Body $Body -Type "Update orgunit" -Old $ExistingOrgUnit -Difference $difference } else { Write-Debug "OrgUnit $($OrgUnit.Key) ($inc / $totalcount) is up to date" } } } if (!$Delta.IsPresent) { $ExistingOrgUnitsMap.GetEnumerator() | Where-Object { $Script:SyncSessionObjects["orgunit"].ContainsKey($_.Key) -eq $false } | ForEach-Object { Write-Verbose "Orgunit $($_.Key) will be deleted" New-PegasusSyncOperation -Method DELETE -Endpoint "/connectors/$($Script:SyncSessionConnectorId)/orgunits/$($_.Value.id)" -Type "Delete orgunit" -Old $_.Value } } } else { Write-Verbose "No org units to sync" } #endregion #region Sync positions if ($Script:SyncSessionObjects["position"]) { Write-Verbose "Syncing positions" $inc = 0 $totalcount = $Script:SyncSessionObjects["position"].Count $Script:SyncSessionObjects["position"].GetEnumerator() | ForEach-Object { $inc += 1 $Position = $_ # $Position = $Script:SyncSessionObjects["position"].GetEnumerator() | Foreach-Object { $_ } | get-random -count 1 Write-Debug "Processing position $($Position.Key) ($inc / $totalcount)" $ExistingPosition = $ExistingPositionsMap[$Position.Key] $Body = @{ sourceid = $Position.Value.sourceid person = $null startdate = $Position.Value.startdate enddate = $Position.Value.enddate primary = $Position.Value.primary ?? $false manager = $null orgunit = $null jobtitle = $Position.Value.jobtitle jobcode = $Position.Value.jobcode employeeid = $Position.Value.employeeid employerid = $Position.Value.employerid customfields = $Position.Value.customfields } if ($Position.Value.person) { $Body.person = $ExistingPersonsMap[$Position.Value.person].id if (!$Body.person) { Write-Warning "Person $($Position.Value.person) does not exist yet, not planning to sync position $($Position.Key) for now" return } else { Write-Debug "Person $($Position.Value.person) maps to $($Body.person)" } } if ($Position.Value.orgunit) { $Body.orgunit = $ExistingOrgUnitsMap[$Position.Value.orgunit].id if (!$Body.orgunit) { Write-Warning "Orgunit $($Position.Value.orgunit) does not exist yet, not planning to sync position $($Position.Key) for now" return } else { Write-Debug "Orgunit $($Position.Value.orgunit) maps to $($Body.orgunit)" } } if ($Position.Value.manager) { $Body.manager = $ExistingPersonsMap[$Position.Value.manager].id if (!$Body.manager) { Write-Warning "Manager person $($Position.Value.manager) does not exist" } else { Write-Debug "Manager person $($Position.Value.manager) maps to $($Body.manager)" } } if (-not $ExistingPosition) { Write-Verbose "Position $($Position.Key) will be created ($inc / $totalcount) - $($Body.firstname) $($Body.lastname)" $ExistingPositionsMap[$Position.Key] = New-PegasusSyncOperation -Method Post -Endpoint "/connectors/$($Script:SyncSessionConnectorId)/positions" -Body $Body -Type "Create position" $ExistingPositionsMap[$Position.Key] } else { $difference = New-Object System.Collections.ArrayList # Determine differences between existing and new position $Body.keys | where-object { $_ -notin "customfields" } | where-object { $Body[$_] -ne $ExistingPosition.$_ } | ForEach-Object { $difference.Add($_) } | Out-Null $Left = $Body.customfields ?? @{} $Right = $ExistingPosition.customfields ?? @{} @($Left.Keys; $Right.Keys) | Sort-Object -Unique | ForEach-Object { $key = $_ if ($Left.$key -cne $Right.$key) { $difference.Add("customfields/$key") | Out-Null } } if ($difference.Count -gt 0) { Write-Verbose "Position $($Position.Key) will be updated (resolved to position id $($ExistingPosition.id)) ($inc / $totalcount) with diff in these attributes: $($difference -join ", ")" Write-Debug "Detailed position change: $($Body | ConvertTo-Json -Depth 10 -Compress) VS $($ExistingPosition | ConvertTo-Json -Depth 10 -Compress)" New-PegasusSyncOperation -Method PATCH -Endpoint "/connectors/$($Script:SyncSessionConnectorId)/positions/$($ExistingPosition.id)" -Body $Body -Type "Update position" -Old $ExistingPosition -Difference $difference } else { Write-Debug "Position $($Position.Key) (resolved to position id $($ExistingPosition.id)) ($inc / $totalcount) is up to date" } } } if (!$Delta.IsPresent) { $ExistingPositionsMap.GetEnumerator() | Where-Object { $Script:SyncSessionObjects["position"].ContainsKey($_.Key) -eq $false } | ForEach-Object { Write-Verbose "Position $($_.Key) will be deleted" New-PegasusSyncOperation -Method DELETE -Endpoint "/connectors/$($Script:SyncSessionConnectorId)/positions/$($_.Value.id)" -Type "Delete position" -Old $_.Value } } } else { Write-Verbose "No positions to sync" } #endregion } } |