Package deployment order of operations

I’m trying to get a better understanding of when powershell deployment scripts are run in relation to other steps in a package deployment. I’m trying to take advantage of the new variable substitution in files functionality to help me generate some powershell script based on variable collections in Octopus to drive some of my config file settings.

I’ve got the variable substitution working fine, and the powershell after substitution is working well too. The question I have is on the order in which Octopus is performing some of these steps.

Looking at the logs, Octopus is deploying a package in the following sequence:

  1. Extracts package to a temporary directory.
  2. Executes any Pre-Deploy powershell for the package.
  3. Performs any config file transformations.
  4. Performs any variable file substitutions.
  5. Copies the package to custom install directory.
  6. Executes Deploy powershell
  7. Executes website or service configuration stuff
  8. Executes Post-Deploy powershell.

What I was expecting to happen is that the Deploy script would execute before the package is copied to the custom install directory. I’m using the variable substitution in files functionality to modify a template powershell script which then makes some changes to a config file. I’d like this powershell to be executed before the package is copied to the custom install directory.

I can’t execute this powershell in Pre-Deploy because the variable substitution hasn’t occurred yet.

I’d like to be able to execute this powershell before the copy to the custom install directory, so I can take advantage of Octopus’s retention policy to preserve previous deployments and the state of any configuration files when they were deployed. This would be a really useful way to do any deployment to deployment config file comparisons to assist with troubleshooting.

Right now, what Octopus is preserving from a deployment retention policy perspective is incomplete in that it doesn’t have a fully transformed config file.

Is there a better way to do what I’m trying to accomplish? Would it make sense to have the Deploy powershell execute before copying to the custom install directory?



Currently there isn’t a way to do this (there’s no AfterPreDeploy.ps1 :)) What you want to do will be able to be accomplished using a plugin model that we plan to build soon. For now, instead of using the substitute in files feature, you might just have to perform the replacement yourself in PreDeploy.ps1.


Thanks for the response! I’ll probably just end up living with the retention policy holding onto config files for older deployments that aren’t fully transformed for now. Or I’ll roll my own config file backup solution.

On a slightly related note, is there a way to access Octopus variables using a similar collection syntax that can be used with the substitute in files feature in powershell? Or a way to pass those collections to powershell? The collection syntax on Octopus variables is awesome.


Hi Joe – I’d very much like to enable the “complex variable” support we use in templates elsewhere, especially PowerShell. Things have stabilised enough in that area now that we should be able to do it at some point.

For now, you can use a bit of a hack to pre-process your PowerShell scripts, detailed at - but only those that run after the “after pre-deploy” phase.

Hope this helps, glad you like the way templating came out, it’s a bit of a favourite underutilized feature here, too!


Thanks Nick. I can’t view the discussion that you referenced. I’m getting a “This discussion is private or deleted” message when I follow the link you posted.


Ah - sorry about that; I’ve copied the relevant message below:

We’ve done some work towards supporting “complex” parameters in Octopus; for example, if you defined your variables like:

DesktopWebsite[App1].Url = http://...
DesktopWebsite[App2].Url = http://

Then, in email templates for example, we roll those values up into a dictionary much like you’re looking for, and you can iterate over them:

#{each site in DesktopWebsite}
The site #{site} is at: #{site.Url}

This will print output like:

The site App1 is at: http://...
The site App2 is at: http://...

I’m including this here because although it is still not very elegant, you can use this template syntax to pre-process your Deploy.ps1 file; just use the template syntax shown above and enable the “Substitute variables in files” feature in your deployment process.

It might be a better long-term approach to managing the variables because (when there’s an opportunity :)) we’d like to support the same rolling up of complex variables into PowerShell scripts making the approach you’d ultimately like to use, work.