How can I aggregate output variable values across targets into a single value?

I have a step named “Set Details” that creates an output variable for many targets.

$target = $OctopusParameters["Octopus.Machine.Name"]

$details = @{
  Comments = ("$target Comment 1", "$target Comment 2", "$target Comment 3")
  StartTime = (Get-Date).ToFileTimeUtc()
}

Start-Sleep 10

$details.EndTime = (Get-Date).ToFileTimeUtc()
$details = $details | ConvertTo-JSON

Set-OctopusVariable -name "Details" -value $details

I want to combine the values from all of the targets into one value that can be used in an email step or written to a file together.

There are two ways for achieving this. The first solution uses a variable and the each keyword in the variable substitution syntax.

#{each machine in Octopus.Action[Set Details].Output}
Machine: #{machine}
- StartTime: #{machine.Details.StartTime}
- EndTime: #{machine.Details.EndTime}
- Comments
#{each comment in machine.Details.Comments}
  - Comment: #{comment}
#{/each}
#{/each}

This will iterate over each machine that has output for the “Set Details” step and write their values to the variable value.

This works but we can see in the screenshot that it doesn’t order the targets.

We can also use the variable substitution syntax in a PowerShell script to craft objects that we can manipulate before writing.

$machines = @()

#{each machine in Octopus.Action[Set Details].Output}
 $machines += "#{machine}"
#{/each}

$machines = $machines | Sort-Object

$machines | ForEach-Object {
  Write-Highlight $_
  
  $details = $OctopusParameters["Octopus.Action[Set Details].Output[$_].Details"] | ConvertFrom-Json
  Write-Highlight "- StartTime: $($details.StartTime)"
  Write-Highlight "- EndTime: $($details.EndTime)"
  Write-Highlight "- Comments"
  $details.Comments | ForEach-Object {
    Write-Highlight "  - $_"
  }
}

This creates the same output but with the targets sorted.