Cannot triiger a command line service installer from Powershell deploy script

I have this piece of PowerShell:

Function Resolve-Service {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true)][String]$serviceName
    )

    Write-Verbose "Resolving Windows service $serviceName..."
    $service = Get-Service $serviceName -ErrorAction SilentlyContinue
    if ($service) { 
        Write-Verbose "Found $serviceName."
        Write-Verbose $service
        return $true 
    } 
    else { 
        Write-Verbose "Did not find $serviceName."
        return $false 
    }        
}

Function Start-Executable {
  [CmdletBinding()]
  Param(
    [String] $FilePath,
    [String[]] $ArgumentList
  )
  Write-Verbose "Starting $FilePath $ArgumentList"
  $guid = [GUID]::NewGuid()
  $tempFile = "$env:TEMP\$guid.tmp"
  Start-Process -FilePath $FilePath -ArgumentList $ArgumentList -NoNewWindow -Wait -RedirectStandardOutput $tempFile
  Get-Content $tempFile | Write-Host
  Remove-Item $tempFile
}

Function Start-ServiceInstaller {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true)][String]$ServiceName,
        [Parameter(Mandatory = $true)][String]$Executable
    )
    $ErrorActionPreference = "stop"
    if(!(Test-Path $Executable)) { Write-Error "$Executable does not exist..." }

    if (Resolve-Service $ServiceName)
    {
        Write-Verbose "Found Windows service $ServiceName"
        Write-Host "The service will be reinstalled: $ServiceName"
        $service = Get-WmiObject Win32_Service | Where {$_.Name -eq $ServiceName}
        Start-Executable $service.PathName "Uninstall"
        
    }
    else { Write-Verbose "Windows service $ServiceName does not exist." }

    
    Start-Executable $Executable "Install"
    Start-Service $ServiceName


}

Calling Start-ServiceInstaller -Executable ".\foo.exe" -ServiceName "foo-service" in the Deploy script fails with:

VERBOSE: Starting .\foo.exe Install
Cannot start service from the command line or a debugger. A Windows Service must first be installed (using installutil.exe) and then started with the ServerExplorer, Windows Services Administrative tool or the NET START command.
Fatal 14:39:17
PowerShell script returned a non-zero exit code: 1
Tentacle version 2.5.11.614

However, when I run this script directly by logging on to the Tentacle computer and executing it in PowerShell it does exacly as expected: Installs the service by running the .exe with the Install parameter.

Hi there

Thanks for getting in touch.

First up, what account is your tentacle running under ?

Looking at your script I’m going to make an assumption your service is built with Topshelf, am I close ? You can install (move) services directly from an Octopus deploy step and that works well with Topshelf services. It might be an easier solution.

We have a page on our wiki which might help http://docs.octopusdeploy.com/display/OD/Windows+Services

Regards

Damian

Tentacle is running as Local System

The service installer is embedded in the assembly using System.ServiceProcess.ServiceInstaller and System.ServiceProcess.ServiceProcessInstaller

I appreciate the Octopus support for installing services with sc.exe but the service will not accept Stop command if I use sc.exe to install and I can not change that.

As an example; using Octopus built-in service support will successfully install the service in a new environment. The next deploy will fail due to the service not accepting Stop command:

The foo-Staging service already exists; it will be stopped Stopping the foo-Staging service
Error 12:02:44
Stop-Service : Service 'Reknes WMS Appserver 13.2.0-alpha828-7 Staging
Error 12:02:44
(foo-Staging)' stop failed.
Error 12:02:44
At C:\Octopus\Applications\.SQ-OES-WS2012-080D2010\Octopus.Tentacle\2.5.11.614\
Error 12:02:44
Scripts\Octopus.Features.WindowsService_AfterPreDeploy.ps1:43 char:5
Error 12:02:44
+ Stop-Service $ServiceName -Force
Error 12:02:44
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error 12:02:44
+ CategoryInfo : OpenError: (System.ServiceProcess.ServiceControl
Error 12:02:44
ler:ServiceController) [Stop-Service], ServiceCommandException
Error 12:02:44
+ FullyQualifiedErrorId : StopServiceFailed,Microsoft.PowerShell.Commands.
Error 12:02:44
StopServiceCommand
Fatal 12:02:44
PowerShell script returned a non-zero exit code: 1

As I see it I have two options:

  1. Find out why the PowerShell script that works from an interactive shell will not work when run from a Tentacle
  2. Lure the System Architect down to my basement and keep him locked in until he can push a version of the service that can be installed by sc.exe

I want to try and figure this out using alternative 1 first, as alternative 2 could spread some unhappiness at work and might be a bit illegal :wink:

Hi there

Well as much as option 2 sounds fun ;)…

I took your script and modified it to run a service executable I have and could get it to work under a tentacle installed as Local Service, so I’m not sure it’s an Octopus problem.

Any group policy things that might be stopping it ? Is the service doing anything odd on registration ?

As much as I hate “Works on my machine”, I don’t think it’s your script or the tentacle that is causing the issue here.

Regards

Damian

Hm. Strange.

The Tentacle is a fresh install of Windows Server 2012 R2 and is placed outside the domain so there shouldn’t be any group policies that I am not aware of.

Also, when I said that the script ran successfull in an interactive PowerShell console, that was done on the actual Tentacle (using my own user account)…

I’ll continue to investigate, will post an update if I find something useful

The plot thickens…

Found this piece of code in the main class for the program:

if (!Environment.UserInteractive)
            {
                ServiceBase.Run(new FooServiceHost());
            }

So I guess Tentacle is running in a non-interactive environment.

The code for parsing the command line parameters comes after this piece of code…

Ha

Well looks like you know who to go and talk to next :slight_smile:

Take a look into the Topshelf Project though, it takes a lot of the pain out of building and running Windows Services, and Octopus will install them easily.

Damian

[Solved]

Changed our implementation to not ignore command line arguments when running in non-interactive mode.