<< Back to Script Library

Restart service associated with process

This script attempts to locate a Windows service associated with a given process and issues it a start command, if not already started.
Version: 1.1.2
Created: 2019-02-17
Modified: 2019-02-24
Creator: Guy Leech
Downloads: 221
Tags: restart service watchdog
The Script Copy Script Copied to clipboard
<#
    Given a process name and optional command line, figure out if it is a service and restart it as notification from ControlUp console will be after process exits
    Path passed must be a full path otherwise if there are two services of the same name we cannot differentiate
    Will not start non-auto start services since they may not be running

    @guyrleech 2019
#>

if( ! $args -or ! $args.Count -or ! $args[0] )
{
    Throw 'Must specify an executable and optional command line parameters'
}

$VerbosePreference = 'SilentlyContinue'

[string]$processName = $null
[string]$arguments = $null

if( $args[0] -match '^"([^"]*)"\s*?(.*)?$' -or $args[0] -match '^([^\s]*)\s*?(.*)?$' )
{
    $processName = $Matches[1]
    $arguments = $Matches[2].Trim()
}
else
{
    Throw "Failed to parse command line: $($args[0])"
}

Write-Verbose "Executable `"$processName`" arguments `"$arguments`""

[array]$matchingServices = @( Get-WmiObject -Class win32_service | ForEach-Object `
{
    ## PathName will either have quotes if it has spaces or not if not and then followed by any arguments
    Write-Verbose $_.PathName
    if( $_.PathName -match '^"([^"]*)"\s*?(.*)?$' -or $_.PathName -match '^([^\s]*)\s*?(.*)?$' )
    {
        if( $Matches[1] -eq $processName )
        {
            if( ( [string]::IsNullOrEmpty( $arguments ) -and ! $Matches[2] ) -or ( ! [string]::IsNullOrEmpty( $arguments ) -and $arguments -eq $Matches[2].Trim() ) )
            {
                Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Executable' -Value $Matches[1]
                Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Arguments' -Value $Matches[2]
                $_
            }
        }
    }
    elseif( $_.PathName )
    {
        Write-Warning "$($_.PathName) did not match regex"
    }
})

if( $matchingServices -and $matchingServices.Count )
{
    ## Now find how many aren't running so we can find the one to restart
    [array]$notRunning = @( $matchingServices | Where-Object { ! $_.Started } )

    Write-Verbose "Found $($matchingServices.Count) matching services of which $($notRunning.Count) are not running"

    if( $notRunning.Count -eq 1 )
    {
        if( $notRunning[0].StartMode -eq 'Auto' )
        {
            ## Just one not running so we can start it
            $startError= $null
            Write-Output "Starting service $($notRunning[0].Name) ($($notRunning[0].DisplayName)) ..."
            $started = Start-Service -Name $notRunning[0].Name -PassThru -ErrorVariable startError
            if( $? )
            {
                if( $started -and $started.Status -eq 'Running' )
                {
                    Write-Output "Started ok"
                }
                else
                {
                    Write-Error "Failed to start - status is $($started.Status)"
                }
            }
            ## else will have already output an error
        }
        else
        {
            Write-Warning "Service $($notRunning[0].Name) ($($notRunning[0].DisplayName)) is of start type $($notRunning[0].StartMode) so may not need to run"
        }
    }
    elseif( $notRunning.Count -eq 0 )
    {
        Write-Error "Found no non-running instances of a service with executable `"$processName`" and arguments `"$arguments`" so cannot restart any services.`nRunning services are: $(($matchingServices|select -expandproperty Name) -join ' , ')"
    }
    else
    {
        Write-Error "Found $($notRunning.Count) non-running services with executable `"$processName`" and arguments `"$arguments`" so cannot restart due to ambiguity`nNon-running services are: $(($notRunning|select -expandproperty Name) -join ' , ')"
    }  
}
else
{
    Write-Warning "Failed to find a service with executable `"$processName`" and arguments `"$arguments`""
}