Public/Get-ConnectorSyncSessionOperation.ps1
|
<# .SYNOPSIS Generates Create, Update, and Delete operations by comparing the sync session objects to existing API data. .DESCRIPTION Fetches the current connector objects from the API and compares them against the objects accumulated in the active sync session (via Add-ConnectorSyncSessionObject). Emits Build-ConnectorOperation hashtables for each required change: - Create: objects present in the session but not in the API. - Update: objects present in both but with differing Data payloads. - Delete: objects present in the API but not in the session. The resulting operations can be piped directly to Complete-ConnectorSyncSessionOperation. .OUTPUTS System.Collections.Hashtable .EXAMPLE Get-ConnectorSyncSessionOperation | Complete-ConnectorSyncSessionOperation .EXAMPLE $ops = Get-ConnectorSyncSessionOperation $ops | Where-Object { $_.OperationType -eq "Delete" } | Complete-ConnectorSyncSessionOperation -WhatIf #> function Get-ConnectorSyncSessionOperation { [CmdletBinding()] param ( [Switch] $AllowEmptySession ) process { if ([String]::IsNullOrEmpty($Script:APIRoot)) { throw "Please connect first" } $GetExistingConnectorObjectsWebResult = Invoke-WebRequest -Uri "$($Script:APIRoot)data" -Headers (Get-EntraIDAccessTokenHeader -Profile $Script:AccessTokenProfile) -Method Get -SkipHttpErrorCheck if($GetExistingConnectorObjectsWebResult.StatusCode -ge 400) { throw "Unable to get connector objects. HTTP Status: $($GetExistingConnectorObjectsWebResult.StatusCode). Response: $($GetExistingConnectorObjectsWebResult.Content)" } $GetExistingConnectorObjectsResult = $GetExistingConnectorObjectsWebResult.Content | ConvertFrom-Json -AsHashtable -Depth 20 if (!$GetExistingConnectorObjectsResult.isSuccess) { throw "Unable to get connector objects" } $ExistingConnectorObjects = @{} if ($GetExistingConnectorObjectsResult.data) { $GetExistingConnectorObjectsResult.data | ForEach-Object { $ExistingConnectorObjects[$_.externalId] = $_ } } Write-Verbose "Found $($ExistingConnectorObjects.Count) existing objects" if ($Script:SyncSessionObjects.Count -gt 0) { $Script:SyncSessionObjects.GetEnumerator() | ForEach-Object { if ($ExistingConnectorObjects.ContainsKey($_.Key)) { Write-Debug "Object $($_.Key) already exists, checking for diff" $ExistingConnectorObject = $ExistingConnectorObjects[$_.Key] $ExistingJSON = ($ExistingConnectorObject.data | ConvertTo-Json -Compress -Depth 20).ToCharArray() $SyncJSON = ($_.Value.data | ConvertTo-Json -Depth 20 -Compress).ToCharArray() $IsDifferent = $ExistingJSON.Length -ne $SyncJSON.Length if (!$IsDifferent) { $IsDifferent = (($SyncJSON | Sort-Object) -join "") -cne (($ExistingJSON | Sort-Object) -join "") } if ($IsDifferent) { Build-ConnectorOperation -OperationType Update -ConnectorObject $_.Value -Id $ExistingConnectorObject.id } } else { Build-ConnectorOperation -OperationType Create -ConnectorObject $_.Value } } } else { if (-not $AllowEmptySession) { throw "No objects in sync session. Use -AllowEmptySession to emit delete operations for all existing objects." } } $ExistingConnectorObjects.GetEnumerator() | ForEach-Object { if (-not $Script:SyncSessionObjects.ContainsKey($_.Key)) { Build-ConnectorOperation -OperationType Delete -ConnectorObject $_.Value -Id $_.Value.id } } } } |