Public/Activities/Get-JIMActivityExecutionItem.ps1
|
# Copyright (c) Tetron Limited. All rights reserved. # Licensed under the Tetron Commercial License. See LICENSE file in the project root. function Get-JIMActivityExecutionItem { <# .SYNOPSIS Gets one Run Profile Execution Item, including its error message, or what caused it or what it caused; or every execution item about one object, each with its nearest cause. .DESCRIPTION Retrieves one execution item of a Run Profile Activity: what happened to one object and, when it failed, why. The list from Get-JIMActivity -ExecutionItems names each failed item's error type; this returns the error message and stack trace too, with the snapshots taken when the item was recorded (the object's external ID, display name and type) and the ids of the Connected System Object, Metaverse Object or Pending Export it is about. With -Causes, returns what caused the item instead, walked back through the causes JIM recorded, and with -Consequences what the item went on to cause, in later runs as well as its own. Both are flattened to one row per cohort (objects sharing a cause and its reason read as one row with a Count), with Level 1 for the nearest and one more per step. A consequences row says in Ending where its branch stopped, and carries the CohortKey that Get-JIMCausalCohortMember pages its members with. With -ConnectedSystemId and -ConnectedSystemObjectId, or with -MetaverseObjectId, returns the object's causal timeline instead: every execution item about it, newest first, each with its nearest recorded cause, as the Causality Explorer lists them. A deleted object's timeline is still read, through the records its deletion left. Item ids come from Get-JIMActivity -ExecutionItems or from a timeline, whose rows can be piped straight in. .PARAMETER Id The execution item to get. The rows of Get-JIMActivity -ExecutionItems can be piped straight in. .PARAMETER IncludeOutcomes Add the item's outcome tree as Outcomes: what the run did to the object, each outcome with the outcomes that followed from it in Children. .PARAMETER IncludeChanges Add the attribute changes recorded with the item as Changes: its Metaverse Object change, its Connected System Object change, and what each Pending Export it staged would write. .PARAMETER Causes Return what caused the item instead, one row per cohort of causes. .PARAMETER Consequences Return what the item went on to cause instead, one row per cohort of consequences. .PARAMETER ConnectedSystemId The Connected System holding the Connected System Object whose timeline to return. .PARAMETER ConnectedSystemObjectId The Connected System Object whose timeline to return. Get-JIMConnectedSystemObject returns it as Id. .PARAMETER MetaverseObjectId The Metaverse Object whose timeline to return. Get-JIMMetaverseObject returns it as Id. .PARAMETER Page The page of the timeline to return, newest items first. .PARAMETER PageSize How many items each page of the timeline holds. .PARAMETER All Return the whole timeline, fetching every page. Stops after 1000 pages with a warning unless -Force is given. .PARAMETER Force Fetch past the 1000-page limit of -All. .OUTPUTS Without a switch, the item; -IncludeOutcomes and -IncludeChanges add its Outcomes and Changes, which are otherwise empty. With -Causes, what caused it, and with -Consequences what it went on to cause, in later runs as well as its own: one row per cohort (objects sharing a cause and its reason read as one row with a Count), with Level 1 for the nearest and one more per step. With an object's id, the object's timeline, one row per execution item, newest first; where the deployment records no Metaverse Object changes, a Metaverse Object's timeline holds only what its joined Connected System Objects recorded, and a warning says so. JIM.ActivityRunProfileExecutionItemDetailDto: With -Id JIM.CauseCohort ExecutionItemId (guid): The execution item the walk started from. Level (int): How many steps back from the item: 1 for its direct causes. EdgeType (CausalEdgeType): The recorded cause; empty for a step to the import that fed a synchronisation, or to the Metaverse Object's creation. SourceImportChangeType (ObjectChangeType): For the step to the import that fed a synchronisation, what that import did: Added, Updated or Deleted. MetaverseChangeType (ObjectChangeType): For the step to the Metaverse Object's creation: Projected, Joined or Created. ReasonCode (CausalReasonCode): Why the cause produced its effect; NotSet where no reason was recorded. Count (int): How many causes the cohort holds. ObjectType (string): The causes' object type, plural where there are several. Attribute (string): The reference attribute the causes acted through, where one applies. ConnectedSystem (string): The Connected System the causes are attributed to, as named when recorded. SyncRule (string): The Synchronisation Rule responsible, as named when recorded. Members (string[]): The causes' names, as recorded. Resolution (string): Why the walk stopped at these causes, for example CauseNotRetained; empty where each carries on to the next level. JIM.ConsequenceCohort ExecutionItemId (guid): The execution item the walk started from. Level (int): How many steps on from the item: 1 for what it directly caused. A Level 0 row gives the item's own ending where it caused nothing. HopKind (CausalConsequenceHopKind): How the consequences were reached: Edge (a recorded cause), Confirmation (the import confirming an export), NextSynchronisation (the synchronisation after an import), OutstandingPendingExport or ScheduledDeletion. EdgeType (CausalEdgeType): The recorded cause, for an Edge or Confirmation hop. ReasonCode (CausalReasonCode): Why the cause produced these consequences; NotSet for any other hop. Count (int): How many consequences the cohort holds, counted exactly. ObjectType (string): The consequences' object type, plural where there are several. Attribute (string): The reference attribute a removal acted through, where one applies. ConnectedSystem (string): The Connected System the consequences are attributed to. SyncRule (string): The Synchronisation Rule the cause names, where it names one. OutcomeSummary (string): The outcomes the consequences share. PendingExportStatus (PendingExportStatus): For outstanding Pending Exports, their live status. Ending (string): Where the branch stops: the cohort's own ending (Confirmed, WaitingForExport, WaitingForRetry, NeedsAttention, WaitingForConfirmingImport or DeletionScheduled), else how many consequences led nowhere further and why, for example "NoFurtherConsequences (2)", else FurtherThanShown where the walk reached its bound. Empty where every consequence carries on. FirstOccurred (datetime): When the earliest consequence happened, in UTC. LastOccurred (datetime): When the latest consequence happened, in UTC. DueAt (datetime): When the soonest outstanding work is due, in UTC: a retry, or a deletion becoming eligible. Members (string[]): The first consequences' names; Get-JIMCausalCohortMember pages through them all. CohortKey (string): The cohort's key, which Get-JIMCausalCohortMember pages its members with. .EXAMPLE Get-JIMActivityExecutionItem -Id "b2c3d4e5-f6a7-8901-bcde-f12345678901" Gets one execution item, with its error message if it failed. .EXAMPLE Get-JIMActivity -Id "a1b2c3d4-e5f6-7890-abcd-ef1234567890" -ExecutionItems | Where-Object { $_.ErrorType -and $_.ErrorType -ne 'NotSet' } | Get-JIMActivityExecutionItem | Select-Object DisplayNameSnapshot, ErrorType, ErrorMessage Lists why each object in a Run Profile execution failed. .EXAMPLE Get-JIMActivity -Id "a1b2c3d4-e5f6-7890-abcd-ef1234567890" -ExecutionItems | Get-JIMActivityExecutionItem | Where-Object { $_.UnresolvedReferenceCount -gt 0 } | Select-Object DisplayNameSnapshot, UnresolvedReferenceCount, ErrorType Lists every object an import left with unresolved references, including those whose item carries a different error. .EXAMPLE (Get-JIMActivityExecutionItem -Id "b2c3d4e5-f6a7-8901-bcde-f12345678901").MatchCandidates | Select-Object DisplayNameSnapshot, MatchedValue, Exists, @{ Name = 'JoinedTo'; Expression = { $_.JoinedObjects.ConnectedSystemName -join ', ' } } Lists the identities an ambiguous match found, the value each matched on, and where each is connected. .EXAMPLE Get-JIMActivity -Id "a1b2c3d4-e5f6-7890-abcd-ef1234567890" -ExecutionItems | Where-Object ObjectChangeType -eq 'Joined' | Get-JIMActivityExecutionItem | Select-Object DisplayNameSnapshot, JoinMatchedValue, JoinObjectMatchingRuleDescriptionSnapshot Lists each object a synchronisation joined, with the value it matched on and the Object Matching Rule that made the join. .EXAMPLE $item = Get-JIMActivityExecutionItem -Id "b2c3d4e5-f6a7-8901-bcde-f12345678901" -IncludeChanges $item.Changes.MetaverseObjectChange.AttributeChanges | Select-Object AttributeName, @{ Name = 'Added'; Expression = { ($_.ValueChanges | Where-Object ValueChangeType -eq 'Add').StringValue } }, @{ Name = 'Removed'; Expression = { ($_.ValueChanges | Where-Object ValueChangeType -eq 'Remove').StringValue } } Shows which Metaverse Object attributes a synchronisation changed, with the text values it added and removed. .EXAMPLE function Get-Outcome($Outcomes) { foreach ($o in $Outcomes) { $o; Get-Outcome $o.Children } } $item = Get-JIMActivityExecutionItem -Id "b2c3d4e5-f6a7-8901-bcde-f12345678901" -IncludeOutcomes Get-Outcome $item.Outcomes | Where-Object OutcomeType -eq 'PendingExportCreated' | Select-Object TargetEntityDescription, SyncRuleName, StagedChangeType Lists the Pending Exports a synchronisation staged for one object, walking the outcome tree to every depth. .EXAMPLE Get-JIMActivityExecutionItem -Id "b2c3d4e5-f6a7-8901-bcde-f12345678901" -Causes | Format-Table Level, EdgeType, ReasonCode, Count, ObjectType, ConnectedSystem, Members Shows what caused an execution item, one row per cohort of causes. .EXAMPLE Get-JIMActivityExecutionItem -ConnectedSystemId 3 -ConnectedSystemObjectId "c3d4e5f6-a7b8-9012-cdef-123456789012" | Format-Table Executed, TargetName, ObjectChangeType, Because Lists what happened to a Connected System Object, newest first, and why. .EXAMPLE Get-JIMActivityExecutionItem -MetaverseObjectId "d4e5f6a7-b8c9-0123-def0-234567890123" -All | Where-Object ObjectChangeType -eq 'Deprovisioned' | Get-JIMActivityExecutionItem -Causes Finds each time a Metaverse Object was deprovisioned somewhere, and walks back through what caused it. .EXAMPLE Get-JIMActivityExecutionItem -Id "b2c3d4e5-f6a7-8901-bcde-f12345678901" -Consequences | Where-Object Ending -like 'Waiting*' | Format-Table Level, HopKind, Count, ObjectType, ConnectedSystem, Ending, DueAt Shows which of an execution item's consequences are still waiting, and on what. .LINK Get-JIMActivity Get-JIMActivityStats Get-JIMCausalCohortMember #> [CmdletBinding(DefaultParameterSetName = 'Item')] [OutputType('JIM.ActivityRunProfileExecutionItemDetailDto', ParameterSetName = 'Item')] [OutputType('JIM.CauseCohort', ParameterSetName = 'Causes')] [OutputType('JIM.ConsequenceCohort', ParameterSetName = 'Consequences')] [OutputType('JIM.CausalTimelineRowDto', ParameterSetName = 'ConnectedSystemObjectTimeline')] [OutputType('JIM.CausalTimelineRowDto', ParameterSetName = 'ConnectedSystemObjectTimelineAll')] [OutputType('JIM.CausalTimelineRowDto', ParameterSetName = 'MetaverseObjectTimeline')] [OutputType('JIM.CausalTimelineRowDto', ParameterSetName = 'MetaverseObjectTimelineAll')] param( # No ActivityId alias: an item's id is not its Activity's, and an object carrying both must bind the item's. [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'Item')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'Causes')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'Consequences')] [guid]$Id, [Parameter(ParameterSetName = 'Item')] [switch]$IncludeOutcomes, [Parameter(ParameterSetName = 'Item')] [switch]$IncludeChanges, [Parameter(Mandatory, ParameterSetName = 'Causes')] [switch]$Causes, [Parameter(Mandatory, ParameterSetName = 'Consequences')] [switch]$Consequences, # The timeline sets bind nothing from the pipeline. A piped Connected System Object or Metaverse Object # carries its own id as Id, which the item sets above already bind by default, so piping one in could only # select a timeline through a switch that existed for nothing else; the object's ids are passed explicitly. [Parameter(Mandatory, ParameterSetName = 'ConnectedSystemObjectTimeline')] [Parameter(Mandatory, ParameterSetName = 'ConnectedSystemObjectTimelineAll')] [int]$ConnectedSystemId, [Parameter(Mandatory, ParameterSetName = 'ConnectedSystemObjectTimeline')] [Parameter(Mandatory, ParameterSetName = 'ConnectedSystemObjectTimelineAll')] [guid]$ConnectedSystemObjectId, [Parameter(Mandatory, ParameterSetName = 'MetaverseObjectTimeline')] [Parameter(Mandatory, ParameterSetName = 'MetaverseObjectTimelineAll')] [guid]$MetaverseObjectId, [Parameter(ParameterSetName = 'ConnectedSystemObjectTimeline')] [Parameter(ParameterSetName = 'MetaverseObjectTimeline')] [ValidateRange(1, [int]::MaxValue)] [int]$Page = 1, [Parameter(ParameterSetName = 'ConnectedSystemObjectTimeline')] [Parameter(ParameterSetName = 'ConnectedSystemObjectTimelineAll')] [Parameter(ParameterSetName = 'MetaverseObjectTimeline')] [Parameter(ParameterSetName = 'MetaverseObjectTimelineAll')] [ValidateRange(1, 100)] [int]$PageSize = 50, [Parameter(Mandatory, ParameterSetName = 'ConnectedSystemObjectTimelineAll')] [Parameter(Mandatory, ParameterSetName = 'MetaverseObjectTimelineAll')] [switch]$All, [Parameter(ParameterSetName = 'ConnectedSystemObjectTimelineAll')] [Parameter(ParameterSetName = 'MetaverseObjectTimelineAll')] [switch]$Force ) process { if (-not $script:JIMConnection) { Write-Error "You are not connected to JIM. Run Connect-JIM -Url <your JIM URL> to authenticate, then try again." return } if ($PSCmdlet.ParameterSetName -like '*Timeline*') { $timelineEndpoint = if ($PSCmdlet.ParameterSetName -like 'ConnectedSystemObject*') { "/api/v1/synchronisation/connected-systems/$ConnectedSystemId/connector-space/$ConnectedSystemObjectId/causal-timeline" } else { "/api/v1/metaverse/objects/$MetaverseObjectId/causal-timeline" } Write-Verbose "Getting causal timeline: $timelineEndpoint" # Said once however many pages are read: a hashtable, so the page request below can mark it from its own # scope. $notice = @{ Given = $false } $pageRequest = { param($p) $response = Invoke-JIMApi -Endpoint "$($timelineEndpoint)?page=$p&pageSize=$PageSize" if ($response.metaverseObjectChangesNotRecorded -and -not $notice.Given) { Write-Warning "This deployment does not record Metaverse Object changes, so the timeline holds only what the object's joined Connected System Objects recorded." $notice.Given = $true } $response } if ($All) { Invoke-JIMPagedFetch -PageRequest $pageRequest -CmdletName 'Get-JIMActivityExecutionItem' -PageSize $PageSize -Force:$Force ` -ItemNoun 'execution items' } else { $response = & $pageRequest $Page foreach ($row in $response.items) { $row } } return } if ($Causes) { Write-Verbose "Getting what caused execution item: $Id" $chain = Invoke-JIMApi -Endpoint "/api/v1/activities/items/$Id/causes" if ($chain) { ConvertTo-JIMCausalCauseRows -Cohorts $chain.Cohorts -ExecutionItemId $Id } return } if ($Consequences) { Write-Verbose "Getting what execution item $Id went on to cause" $walk = Invoke-JIMApi -Endpoint "/api/v1/activities/items/$Id/consequences" if ($walk) { ConvertTo-JIMCausalConsequenceRows -Consequences $walk } return } Write-Verbose "Getting execution item with ID: $Id" $include = @( if ($IncludeOutcomes) { 'outcomes' } if ($IncludeChanges) { 'changes' } ) $endpoint = "/api/v1/activities/items/$Id" if ($include.Count -gt 0) { $endpoint += "?include=$($include -join ',')" } Invoke-JIMApi -Endpoint $endpoint } } |