jabbera / my-vsts-tasks

20 stars 18 forks source link

Feature Request: Support wildcards in service name for Start-Service and Stop-Service #19

Closed deadlydog closed 6 years ago

deadlydog commented 6 years ago

When we install our Windows Services, we use the version number as part of the service name. This is very helpful in determining which version of a service is actually running in an environment or on a specific server. Also, we have some programs where we purposely have different versions of the service running side-by-side. As such, when it comes time to stop/uninstall the older service, we don't necessarily know it's full name, since the deployment doesn't know what version was previously deployed to that environment.

The native PowerShell Get-Service cmdlet already supports using wildcards for getting services by name, so I'm hoping it would be a fairly easy change to have your Stop-Service and Start-Service tasks support wildcards (i.e. *) being used in the service name.

The workaround right now is to run a custom powershell script first that does Get-Service -Name MyPartialServiceName* and save that to a VSTS Release Management variable as a comma separated string, and then pass that into your tasks. If your tasks supported wildcards natively, it would eliminate that additional custom task/logic and would help keep things much cleaner.

Thanks!

deadlydog commented 6 years ago

I've created PR #20 to address this issue :)

deadlydog commented 6 years ago

Thanks for merging in the Pull Request. Any idea when the new version will be pushed out and made available in the marketplace @jabbera?

jabbera commented 6 years ago

I’ve ran into a few bugs in the code that I have not worked out yet. Stop service doesn’t work when no services exist. Start service is complaining that no + operator exists on service base even though you have defined the array as a pscustomobject.

Mike

Sent from my iPhone.

On Dec 5, 2017, at 8:00 PM, Daniel Schroeder notifications@github.com wrote:

Thanks for merging in the Pull Request. Any idea when the new version will be pushed out and made available in the marketplace @jabbera https://github.com/jabbera?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jabbera/my-vsts-tasks/issues/19#issuecomment-349494220, or mute the thread https://github.com/notifications/unsubscribe-auth/AASYmGwc1h-F-_uUyS4kwSiyz9VeNbIwks5s9edGgaJpZM4QdwEI .

deadlydog commented 6 years ago

Hmmm, that's odd. Stop service should just display a Verbose message that no services exist. Does it actually throw an error message instead?

For the array, perhaps using .Add(item) would work better instead of the += operator?

Thanks for the update 👍

jabbera commented 6 years ago

I’ll try add. Get-Service errors if the service name does not exist (at least on my version of powershell) see: https://github.com/jabbera/my-vsts-tasks/commit/b0788ded7fa45856a37b156fe5aa526dc9691325

For the fix I made.

deadlydog commented 6 years ago

Any progress on this one? Thanks.

jabbera commented 6 years ago

Hi,

Feel free to try the beta. Let me know how it goes. https://github.com/jabbera/my-vsts-tasks/releases/tag/6.189.1

jabbera commented 6 years ago

Any update here?

deadlydog commented 6 years ago

Hey @jabbera. I just installed the latest version and gave it a try. It didn't fail, but it also didn't stop the service. Here's the log output:

******************************************************************************
Starting: Stop the Windows Service in case we are redeploying an existing version
******************************************************************************
==============================================================================
Task         : Stop Windows Service
Description  : Stop a windows service.
Version      : 4.17297.1
Author       : Michael Barry
Help         : Version: 4.17297.1 [More Information](https://github.com/jabbera/my-vsts-tasks)
==============================================================================
Stopping Windows Service:  and setting startup type to: Disabled. Kill: true Version: 4.17297.1
ScriptArguments: -serviceNames "IQ.PlatformPushService*" -startupType Disabled -waitTimeoutInSeconds 120 -killIfTimedOut true
Invoking deployment
Script Body: function StartStopServices(
    [string][Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()] $serviceNames,
    [string][Parameter(Mandatory=$true)][ValidateSet("Disabled", "Manual", "Automatic")] $startupType,
    [int][Parameter(Mandatory=$true)] $waitTimeoutInSeconds,
    [string][Parameter(Mandatory=$true)] $killIfTimedOut
)
{
    [string[]] $servicesNamesArray = ($serviceNames -split ',' -replace '"').Trim()
    $presentServicesArray = Get-Service | Where-Object { $servicesNamesArray -contains $_.Name }
    if ($servicesNamesArray.Length -ne $presentServicesArray.Length)
    {
        $missingServiceNames = $servicesNamesArray | Where-Object { $presentServicesArrayNames -notcontains $_ }
        Write-Verbose "No such services: $missingServiceNames."
    }
    if ($presentServicesArray.Length -eq 0)
    {
        return
    }
    try
    {
        $presentServicesArray | % { Set-Service -Name $_.Name -StartupType $startupType -ErrorAction SilentlyContinue }
        $presentServicesArray | Where-Object { $_.Status -ne "Stopped" } | % { $_.Stop() }
        $ErrorActionPreference = "SilentlyContinue" # I don't want the wait for status to throw in the case of a timeout
        $presentServicesArray | % { $_.WaitForStatus("Stopped", [TimeSpan]::FromSeconds($waitTimeoutInSeconds)) }
        $ErrorActionPreference = "Stop"
    }
    Catch
    {
        $ErrorActionPreference = "Stop"
        if ($killIfTimedOut -eq "false")
        {
            $errorMessage = $_.Exception.Message
            Write-Verbose $errorMessage     
            throw
        }
        $nonStoppedServices = $presentServicesArray | Where-Object { $_.Status -ne "Stopped" } | % { $_.ServiceName }
        $nonStoppedServices | % { Write-Verbose "Killing service after not stopping within timeout: $_" }
        (get-wmiobject win32_Service | Where-Object { $nonStoppedServices -contains $_.Name }).ProcessID | % { Stop-Process -Force $_ }
    }
    Finally
    {
        $presentServicesArray | % { Set-Service -Name $_.Name -StartupType $startupType }
    }
}

 StartStopServices -serviceNames "IQ.PlatformPushService*" -startupType Disabled -waitTimeoutInSeconds 120 -killIfTimedOut true 
Performing deployment in parallel on all the machines.
Deployment started for machine: IQ-RGTestCol006.iqmetrixho.local with port 5985.
Deployment status for machine IQ-RGTestCol006.iqmetrixho.local : Passed

I don't see my PR code changes applied in the output, so either I didn't update/install the extension correctly, or the changes did not make it into https://github.com/jabbera/my-vsts-tasks/releases/tag/6.189.1?

jabbera commented 6 years ago

That's still running with version 4: See line 6 ish: Version : 4.17297.1. It's a major version change. Have you toggled the version in your release?

deadlydog commented 6 years ago

You were right; I had updated the extension itself, but not updated the Task on my Release Definition from v4 to v6. I updated it to v6 and it's working as intended now, supporting wildcards 👍 Thanks!