Octopus API Powershell Deployment details

I want the user to enter the Project Name, release version and the ENV. Powershell to output the Project Name, Release version, Package, Package Version, package installation path,Date of deployment and the user who has deployed it.

So far I’ve got most of this down accept package installation path and the user.

 param (
  [Parameter(Mandatory=$true)]
  [string]$CheckEnvironment,
  [Parameter(Mandatory=$true)]
  [string]$releaseVersion,
  [Parameter(Mandatory=$true)]
  [string]$project_name
 )


Add-Type -Path '.\Octopus.Client.dll'


$apikey = 'API-KEY'
$OctopusURI = 'http://servername/'



$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURI,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint



$project = $repository.Projects.FindByName("$project_name")
$environment = $repository.Environments.FindByName($CheckEnvironment)
$deployments=$repository.Deployments.FindAll()| Where-Object {$_.ProjectId -eq $project.Id}


#put something on the screen
Write-Host "Listing Application releases in environment: $CheckEnvironment"
$msg="Application,Release Number,Package,Package Version,Environment,CompletedTime,Duration,State"
Write-Host $msg

foreach ($d in $deployments)
{   

    
    
    $project=$repository.Projects.Get($d.ProjectId)
    $release=$repository.Releases.Get($d.ReleaseId)
    $task=$repository.Tasks.Get($d.TaskId)
    $environment=$repository.Environments.Get($d.EnvironmentId)
    
    
   foreach($package in $release.SelectedPackages)
   {  

   if ($release.Version -eq $releaseVersion -and $environment.Name -eq $CheckEnvironment)
   {

    $msg = $project.Name
    $msg = $msg + ", " + $release.Version 
    $msg = $msg + ", " + $package.ActionName  
    $msg = $msg + ", " + "Package Version " + $package.version
    $msg = $msg + ", " + $environment.Name 
    $msg = $msg + ", " + $task.CompletedTime
    $msg = $msg + ", " + $task.Duration
    $msg = $msg + ", " + $task.State
    $msg

   
    }
}
 
 }

I found a script on here which can get me the user from the taskid

$serverTasksID = "ServerTasks-12345"

$repository.Events.FindMany(
    {param($e) if(($e.Category -match "Queued") -and ($e.RelatedDocumentIds -contains $serverTasksID))
        {
        #$True # This is optional and returns the entire event object.
        Write-Host "The account which :" $e.message ": Was :" $e.username -Verbose
        }
       
    })
    
}    

However it takes 30 mins to run, I’m not sure why? Apologies for the long post but is there a way to find the package installation path. Why does getting the username take 30 mins to run?

Thanks

Hi @daniel.witter,

Thanks for getting in touch with Octopus!

Deployed by user


Firstly, the user query you mentioned taking 30 minutes probably takes that long as it is querying the Events table which is what powers the audit system.

If you are anything like me and been a long time user of Octopus, the table will grow quickly, as we don’t purge that table for full traceability of events. Therefore querying it may take time.

I think the information you are after for the user who did the deployment is already available from the result of this call:

$deployments=$repository.Deployments.FindAll()| Where-Object {$_.ProjectId -eq $project.Id}

Each deployment has 2 properties:

  • DeployedBy and
  • DeployedById

For completeness, I added the properties listed here to your query:

param (
  [Parameter(Mandatory=$true)]
  [string]$CheckEnvironment,
  [Parameter(Mandatory=$true)]
  [string]$releaseVersion,
  [Parameter(Mandatory=$true)]
  [string]$project_name
)

Add-Type -Path '.\Octopus.Client.dll'

$apikey = 'API-KEY'
$OctopusURI = 'http://servername/'

$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURI,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint

$project = $repository.Projects.FindByName("$project_name")
$environment = $repository.Environments.FindByName($CheckEnvironment)
$deployments = $repository.Deployments.FindAll()| Where-Object {$_.ProjectId -eq $project.Id}

# put something on the screen
Write-Host "Listing Application releases in environment: $CheckEnvironment"
$msg="Application,Release Number,Package,Package Version,Environment,CompletedTime,Duration,State, DeployedBy"
Write-Host $msg

foreach ($d in $deployments)
{   
    $project=$repository.Projects.Get($d.ProjectId)
    $release=$repository.Releases.Get($d.ReleaseId)
    $task=$repository.Tasks.Get($d.TaskId)
    $environment=$repository.Environments.Get($d.EnvironmentId)
    
    foreach($package in $release.SelectedPackages)
    {  
        if ($release.Version -eq $releaseVersion -and $environment.Name -eq $CheckEnvironment)
        {
            $msg = $project.Name
            $msg = $msg + ", " + $release.Version 
            $msg = $msg + ", " + $package.ActionName  
            $msg = $msg + ", " + "Package Version " + $package.version
            $msg = $msg + ", " + $environment.Name 
            $msg = $msg + ", " + $task.CompletedTime
            $msg = $msg + ", " + $task.Duration
            $msg = $msg + ", " + $task.State
            $msg = $msg + ", " + $d.DeployedBy + " (" + $d.DeployedById + ")"
            $msg
        }
    }
 }

Package installation path


Unfortunately, I don’t believe the package installation path is available from the call to the API that you are making. The reason for this is that the path is determined at deployment time - as each deployment target may be configured differently for storing packages, alongside the possibility of deployments making use of a Custom Install Directory too.

The only way I could think that you could get this data, and I’ll admit it’s not an elegant solution would be to write out the installation path after package extraction in the task log and then query the task log and extract the information from the task log. It’s not that nice as the task logs can be large in size and therefore it isn’t the most efficient method.

I hope that helps :slight_smile:

Happy Deployments!
Mark

Hi Mark,

Thanks for the response, I shall leave the installation path part alone then as it’s not a deal breeaker. DeployedBy isn’t an object I can see so when I try $d.DeployedBy it’s coming up blank unfortunately.

Hi @daniel.witter

Ah, yes it’s possible that the API is returning it on my instance as I am running version 2020.2

What version of Octopus Server are you running?

Kind Regards
Mark

Hi @daniel.witter

With the help of a colleague I managed to make a call to the Events page to get the information. I’d be interested to see how long it takes to run on your instance.

As you are using the Octopus Client from powershell, the call looks rather more verbose than it should do. I’d consider calling the API invoking it using Invoke-WebRequest directly instead.

Anyway, the call to get the username from the events looks like this:

$taskId=$task.Id

$skip=0
$take=$null
$from=$null
$to=$null
$regarding=$null
$regardingAny=$taskId
$includeInternalEvents=$true
$user=$null
$users=$null
$project=$null
$environments=$null
$eventGrups=$null
$eventCategories="DeploymentQueued"
$tenants=$null
$tags=$null
$fromAutoId=$null
$toAutoId=$null
$documentTypes=$null
$eventAgents=$null

$event = $repository.Events.List($skip,$take,$from,$to,$regarding,$regardingAny,$includeInternalEvents,$user,$users,$project,$environments,$eventGroups,$eventCategories)
            
$deployEvent = $event.Items | Select-Object -First 1
$deployedBy = $deployEvent.Username + " (" + $deployEvent.UserId + ")"

And for completeness, the entire script:

param (
  [Parameter(Mandatory=$true)]
  [string]$CheckEnvironment,
  [Parameter(Mandatory=$true)]
  [string]$releaseVersion,
  [Parameter(Mandatory=$true)]
  [string]$project_name
)

Add-Type -Path './Octopus.Client.dll'

$apikey = 'API-KEY'
$OctopusURI = 'http://servername'
$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURI,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint

$project = $repository.Projects.FindByName("$project_name")
$environment = $repository.Environments.FindByName($CheckEnvironment)
$deployments = $repository.Deployments.FindAll()| Where-Object {$_.ProjectId -eq $project.Id}

# put something on the screen
Write-Host "Listing Application releases in environment: $CheckEnvironment"
$msg="Application,Release Number,Package,Package Version,Environment,CompletedTime,Duration,State, DeployedBy"
Write-Host $msg

foreach ($d in $deployments)
{   
    
    $project=$repository.Projects.Get($d.ProjectId)
    $release=$repository.Releases.Get($d.ReleaseId)
    $task=$repository.Tasks.Get($d.TaskId)
    $environment=$repository.Environments.Get($d.EnvironmentId)
    
    foreach($package in $release.SelectedPackages)
    {  
        if ($release.Version -eq $releaseVersion -and $environment.Name -eq $CheckEnvironment)
        {
            $taskId=$task.Id

            $skip=0
	        $take=$null
	        $from=$null
	        $to=$null
	        $regarding=$null
	        $regardingAny=$taskId
	        $includeInternalEvents=$true
	        $user=$null
	        $users=$null
	        $project=$null
	        $environments=$null
	        $eventGrups=$null
	        $eventCategories="DeploymentQueued"
	        $tenants=$null
	        $tags=$null
	        $fromAutoId=$null
	        $toAutoId=$null
	        $documentTypes=$null
	        $eventAgents=$null

            $event = $repository.Events.List($skip,$take,$from,$to,$regarding,$regardingAny,$includeInternalEvents,$user,$users,$project,$environments,$eventGroups,$eventCategories)
            
            $deployEvent = $event.Items | Select-Object -First 1
            $deployedBy = $deployEvent.Username + " (" + $deployEvent.UserId + ")"

            $msg = $project.Name
            $msg = $msg + ", " + $release.Version 
            $msg = $msg + ", " + $package.ActionName  
            $msg = $msg + ", " + "Package Version " + $package.version
            $msg = $msg + ", " + $environment.Name 
            $msg = $msg + ", " + $task.CompletedTime
            $msg = $msg + ", " + $task.Duration
            $msg = $msg + ", " + $task.State
            $msg = $msg + ", " + $deployedBy
            $msg          
        }
    }
 }

Hopefully, that will work on your Octopus version!

Thanks, Mark

Hi Mark,

I’m currently running 2019.9.6 LTS so that’s interesting to know moving forward if we upgrade. I will give the code below a go and get back to you.

Thanks,

Dan

1 Like

That worked like a dream, thank you very much for your help.

Hi @daniel.witter

I’m glad that worked for you, you are welcome! :slight_smile:

Happy Deployments!
Mark

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.