How Can I Send a Custom Script via the API or OctoTools?

How can I send a custom script via the API or OctoTools?

For example:

#Adding libraries
Add-Type -Path "C:\Test\Newtonsoft.Json.dll"
Add-Type -Path “C:\Test\Octopus.Client.dll”
#Add-Type -Path “C:\Test\Octopus.Platform.dll”

#Connection variables
$apikey = “API-SomeAPI”
$OctopusURI = “http://OctopusServer/

#Creating a connection
$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURI,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint

$command =
@"
(Invoke-RestMethod http://ipinfo.io/json).ip
@"

$repository.Tasks.Create # send the $command ???

Hello,

Thanks for getting in touch. If you’re trying to execute a few commands against Octopus API we have many great examples of common scripted actions at this GitHub repository: https://github.com/OctopusDeploy/OctopusDeploy-Api

Just a note, you’re using Invoke-RestMethod and we’re using Invoke-WebRequest in our examples, also try restructuring your calls to use web request.

As an example say you wanted to get a project, the code call would look like this:

$Project = Invoke-WebRequest -Uri "$OctopusURL/api/projects/$ProjectName" -Headers $Header| ConvertFrom-Json

That example is from this file: https://github.com/OctopusDeploy/OctopusDeploy-Api/blob/master/REST/PowerShell/Deployments/CreateReleaseAndDeploymentSkippingSteps.ps1#L14

The Octopus Tools includes octo.exe, it’s a command line, and the documentation page for it is here: https://octopus.com/docs/api-and-integration/octo.exe-command-line

An example of using Octo.exe to create a release looks like this:

octo deploy-release --project HelloWorld --releaseNumber 1.0.0 --deployto Production --server http://octopus/ --apiKey API-ABCDEF123456

Which I copied from this page: https://octopus.com/docs/api-and-integration/octo.exe-command-line/deploying-releases#Deployingreleases-Basicexamples

If you’re still having trouble getting started, could you expand on your question of send a custom script via the API and what you’re trying to achieve, so we can give you more direct guidance.

Regards,
Nick

Sorry if I wasn’t clear. From the UI, I can go to
http://myOctopusServer/app/manage/console, where I can send a custom
powershell script to a tentacle. That’s what I’m trying to do. The
command that I’m trying to send is in my $command variable in my powershell.

$command =
@"
(Invoke-RestMethod http://ipinfo.io/json).ip
http://help.octopusdeploy.com/discussions/questions/12769/r?go=aHR0cDovL2lwaW5mby5pby9qc29uKS5pcA==

@"

It happened to contain the invoke-restmethod, which is the very command
that I wanted to run on tentacles. (Incidentally, that was copied from
here:
https://gallery.technet.microsoft.com/scriptcenter/Get-ExternalPublic-IP-c1b601bb)
but that has nothing to do with how I’m connecting to the Octopus server,
be it via invoke-webrequest or otherwise.

Avraham Y. Seff

Hi Avraham,

Thanks for clarifying . The structure of the request body needs to look like this, with the specific machines you want to run it on:

  "Arguments": {
    "ScriptBody": "echo \"first line\"\necho \"second line\"",
    "Syntax": "PowerShell",
    "MachineIds": [
      "Machines-1",
      "Machines-2"
    ]
  }

In your case you want to have a few items in the ScriptBody. If you make use of the developer tools in your browser, and watch the network window you, can paste your script into the app, and run it by hand. Then you’ll see what formatting takes places to get ScriptBody. See attached screen shot where you’ll be able to inspect the payload when you use the Octopus UI to do the action.

Here is the model in Octopus.Client: https://github.com/OctopusDeploy/OctopusClients/blob/master/source/Octopus.Client/Model/BuiltInTasks.cs#L51

Regards,
Nick

Great. thanks. How do I get the output response (task log)?

Avraham Y. Seff

Hi Avraham,

On that initial web request, when you submit the task, you’ll get a response back with the Id:

{
  "Id": "ServerTasks-7945",
  "Name": "AdHocScript",
...

If you then hit the task API api/tasks/ServerTasks-7945 you’ll get a response back with "State": "Executing", you may have to poll with a big wait depending how long you expect your script run to take:

{
  "Id": "ServerTasks-7945",
  "Name": "AdHocScript",
  "Description": "Script run from management console",
  "Arguments": {
    "ScriptBody": "echo \"hello\"",
    "Syntax": "PowerShell",
    "MachineIds": [
      "Machines-2"
    ]
  },
  "State": "Executing",

You’ll want to wait until it says Success, (and possibly code for the Failed, Canceled and TimedOut cases)

The states are:

public enum TaskState
{
	Queued,
	Executing,
	Failed,
	Canceled,
	TimedOut,
	Success,
	Cancelling,
}

When the result shows it has status Success call the task/{id}/details, e.g: /api/tasks/ServerTasks-7945/details?verbose=false&tail=20 API endpoint and you’ll get a response that has ActivityLogs , Children, LogElements in it, and you’ll want to dig into that to get the data you need (see screenshot).

Regards,
Nick