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.
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.
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:
Find out why the PowerShell script that works from an interactive shell will not work when run from a Tentacle
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
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.
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
Well looks like you know who to go and talk to next
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.