Output Variable - Incorrectly passing null value

I want to pass a value in Octopus from one step to another of a project via output variable, the value is “VM running” or “VM deallocated”.
There are two server, one of the server is down, another one is running so values should be passed accordingly. Now when I use the exact syntax of Output variable, it is passing Null value to next step.

Octopus deploy Project Step 1:

$RG = $RGName
$VM = "#{StepTemplate_VMName}"
$WarningPreference = 'SilentlyContinue'
$VMStats = (Get-AzureRmVM -Name $VM -ResourceGroupName $RG -Status).Statuses
$stats = ($VMStats | Where Code -Like 'PowerState/*')[0].DisplayStatus

Set-OctopusVariable -name "RunStatus" -value $stats
write-host $stats     #value can either be "VM running" or "VM deallocated"

Octopus deploy Project Step 2:

$VM = "#{StepTemplate_VMName}"
$Runstatus = $OctopusParameters["Octopus.Action[Step1].Output[$VM].RunStatus"]
write-host $Runstatus

If I do not use [$VM] in the code of step 2, it give only 1 value to both the machine as “VM running”
As per the syntax given in Octopus website, we should use the VM name to pass machine specific different values.
so I used [$VM] but it gives null values to both of the machine

Hi @prathamesh_wagh,

Thanks for getting in touch!

I don’t see any immediate problems with what you’re doing, so my initial thought would be that the problem lies somewhere in the deployment target name being used in step 2.

The $VM value needs to exactly match the deployment target name used within Octopus for the targets used in step 1. I don’t know what value #{StepTemplate_VMName} is using but I’m wondering if it could be retrieving a VM hostname that is different than the deployment target name.

It would be worth performing a test of this by removing the $VM variable temporarily to ensure that the process is working as expected.

In step 2, if you add a second $Runstatus line and manually input the deployment target names, does it output the values you expect?
e.g.

#$VM = "#{StepTemplate_VMName}"
$Runstatus = $OctopusParameters["Octopus.Action[Step1].Output[deploymentTargetOne].RunStatus"]
$Runstatus2 = $OctopusParameters["Octopus.Action[Step1].Output[deploymentTargetTwo].RunStatus"]
write-host $Runstatus
write-host $Runstatus2

Let me know how this goes.

Regards,
Paul

I tried using the VM names directly instead of variable $VM, it still returns me null value.
I believe Octopus is breaking while passing a machine specific output variable.
Also My host name are same as my deployment target name.
#{StepTemplate_VMName} = #{Octopus.Machine.Name}

Ok, thanks for testing that.

Can you confirm what version of Octopus Server you are currently running?
I can then run a test on that version to see if there is a bug here.

Octopus version 3.17.14, thank you for your prompt reply!

Thanks for confirming.
With that being an older version, it is possible that the ability to add output variables for multiple machines may be a feature that was added in a later version. I’ll run through a test on it to confirm.

Whilst I am doing that, another test that would be useful is adding the following variable to your project. This will then write out all variables to the Raw deployment log and allow you to check what values are being captured, including output variables.
e.g.

09:24:06 Verbose | [Octopus.Action[Step 1].Output[WebServer1].RunStatus] = 'VM running' 
09:24:06 Verbose | [Octopus.Action[Step 1].Output[WebServer1].Octopus.Action.Script.ExitCode] = '0' 
09:24:06 Verbose | [Octopus.Action[Step 1].Output[WebServer2].RunStatus] = 'VM running' 
09:24:06 Verbose | [Octopus.Action[Step 1].Output[WebServer2].Octopus.Action.Script.ExitCode] = '0'

The variable to add is OctopusPrintEvaluatedVariables and set the value to true

Thanks for the suggestion, in raw log I found that the $VM is getting replaced by VM name, but still variable $Runstatus is giving null value.

I’ve run a test on that version and I don’t see the variable being split between different machines like I did in my example above.
I only see the single variable [Octopus.Action[Step 1].Output.RunStatus] there aren’t with the deployment target name included.

Do you see differently in your log? Feel free to attach the deployment log or email it to support@octopus.com and I can take a look through it too.

This doesn’t work in any version.
And the information given in below link doesn’t work either, the discussion section of that page too says so.

Hi @prathamesh_wagh,

How do you mean that this doesn’t work in any version? Have you been able to test this on our latest build?

The Fun with output variables link demonstrates how output variables works with multiple deployment targets saving multiple values respective to deployment target.
I ran the exact code in newer version and it did not work.

OK, that is a very old blog post so may not be 100% accurate anymore.

What version did you test this in?

When I tested your initial example in a recent version, it ran without any problems. I was able to get individual results from different deployment targets.
The version you were running (3.17.14) for some reason seems to be missing the per machine variables that I would expect to see.

e.g.
In our most recent version, I see system variables for each machine like so:

[Octopus.Action[Step 1].Output[WebServer1].RunStatus] = 'VM running' 
[Octopus.Action[Step 1].Output[WebServer2].RunStatus] = 'VM not running' 

However, when I ran the same scenario in 3.17.14, those variables didn’t exist at all, there was only the single [Octopus.Action[Step 1].Output.RunStatus] variable. This will be why you are receiving null values because the variable just doesn’t exist.
I’m not sure why this variable doesn’t exist in this version when it seems the feature was added much earlier, but the only solution would be to update.

Thanks @paul.calvert for all your help and efforts on this!!
The only option I can see is updating Octopus version to latest!