Starting OctopusDeploy Tentacle Services Remotely

Background Story

To make a long story short, we had a major server outage at work due to a storage issue. A team got the servers back online, but for some unknow reason, many of the OctopusDeploy Tentacles on a good number of machines did not start up and they were showing as Unavailable in our OctopusDeploy site. I had remembered reading that the OctopusDeploy site uses a web API to get its data to show on the site. I wondered if I could write a PowerShell script and start the OctopusDeploy Tentacle service on all of the servers that had it turned off because I thought it would be faster than remote connecting to the machine, opening the local services and starting the tentacle service. It worked and it was easier than I had expected.

The Script to Start OctopusDeploy Tentacle Service Remotely

Unfortunately, I consider this PowerShell script to be a hack-in-progress. You will need to do some tweaks to it to get it to work for your installation, but never fear, they are minor.

# This script is intended to start the OctopusDeploy Tentacle service on remote windows servers that are showing as
# Unavailable in the OctopusDeploy site.

#https://github.com/OctopusDeploy/OctopusDeploy-Api/wiki/Authentication
$apiKey = '-Put your API Key Here-'
$apiHeaders = @{'X-Octopus-ApiKey'=$apiKey}

# Put additional environmentIds parameter if you want to scope this to specific environments.
# seperator - %2C
# Environments-1
# Environments-2

$apiUrl = 'https://deployserver/api/machines?skip=0&take=2147483647&roles=&isDisabled=false&healthStatuses=Unavailable'
#$apiUrl = 'https://deployserver/api/machines?skip=0&take=2147483647&roles=&isDisabled=false&healthStatuses=Unavailable&environmentIds=Environments-1%2CEnvironments-2'

$apiRequestReturn = Invoke-WebRequest -URI $apiUrl -Method GET -Headers $apiHeaders

# show the status code - If it is 200 then it worked perfectly.
$apiRequestReturn.StatusCode
$items = (ConvertFrom-Json $apiRequestReturn.Content).Items
# filter down to a list of objects with one property -- Name, which is name of the server/deployment target
$computers = $items | Select-Object -Property 'Name'

foreach ($computer in $computers) {
    $name = $computer.Name
    "Starting service on $name"
    #Get-Service -Name 'OctopusDeploy Tentacle' -ComputerName $name
    Get-Service -Name 'OctopusDeploy Tentacle' -ComputerName $name | Start-Service
}

How to Use the Script

To use the script, copy the script and put it in an editor. Next, you’ll need to generate an API Key in your OctopusDeploy site. After you get the API key, paste it into the script where it says, “-Put your API Key Here-” in the script.

Adjust the host $apiUrl to your OctopusDeploy host, and if you want to filter by environment or other option, do that next. You can also use a web browser to see what the URLs are or Fiddler can help with that too.

Save the updates and now you should be ready to run the script. Go ahead and execute it and check the output for any errors.

How I Figured this Out

I already knew that PowerShell can call a web API and get some JSON, (and there are lots of examples of how to do this on the world wide web). However, I needed to know what the URL was to get the API data I needed. To figure out this part, I used Fiddler and my web browser while on the infrastructure page with the filters on to get the unavailable tentacles. Using fiddler, I was able to see which call returned the JSON with the data in it that I wanted, plus where the data was in the JSON that I needed. In this case, it was the name of the servers.

The next concern I had was how to authenticate with the Octopus API. I did a quick search and found that I can add the API key to the header.

After I did that, I added the part to start a windows service, and finally I did a little testing with it.

Limitations

This script assumes that all of the deployment targets are Windows computers running the OctopusDeploy Tentacle service, which may not be the case in your situation. I am also assuming that permissions and configurations for PowerShell are set-up for you to get a service on a remote computer and start that service.

Conclusions

This script really saved me a lot of time. I hope you find it useful and will add it to your arsenal of favorite scripts to fix issues that come up from time to time. Ideally, if something like this happens to you, I think that you should consider modifying the settings in the Recovery tab of the Properties of the OctopusDeploy Tentacle service so if it fails to start, it will automatically try again later and you won’t even need this script, but if you haven’t done that and you’re in a hurry, this script can really come in handy. It was also my first attempt at using the Octopus API.