Public/Service/Start-CWAA.ps1
|
function Start-CWAA { <# .SYNOPSIS Starts the ConnectWise Automate agent services. .DESCRIPTION Verifies that the Automate agent services (LTService, LTSvcMon) are present. Checks for any process using the LTTray port (default 42000) and kills it. If a protected application holds the port, increments the TrayPort (wrapping from 42009 back to 42000). Sets services to Automatic startup and starts them via sc.exe. Waits up to one minute for LTService to reach the Running state, then issues a Send Status command for immediate check-in. .EXAMPLE Start-CWAA Starts the ConnectWise Automate agent services. .EXAMPLE Start-CWAA -WhatIf Shows what would happen without actually starting the services. .NOTES Author: Chris Taylor Alias: Start-LTService .LINK https://github.com/christaylorcodes/ConnectWiseAutomateAgent #> [CmdletBinding(SupportsShouldProcess = $True)] [Alias('Start-LTService')] Param() Begin { Write-Debug "Starting $($MyInvocation.InvocationName)" # Identify processes that are using the tray port [array]$processes = @() $Port = (Get-CWAAInfo -EA 0 -Verbose:$False -WhatIf:$False -Confirm:$False -Debug:$False | Select-Object -Expand TrayPort -EA 0) if (-not ($Port)) { $Port = '42000' } $startedSvcCount = 0 } Process { if (-not (Get-Service 'LTService', 'LTSvcMon' -ErrorAction SilentlyContinue)) { if ($WhatIfPreference -ne $True) { Write-Error "Services NOT Found." } else { Write-Error "What If: Services NOT Found." } return } Try { if ((('LTService') | Get-Service -EA 0 | Where-Object { $_.Status -eq 'Stopped' } | Measure-Object | Select-Object -Expand Count) -gt 0) { Try { $netstat = & "$env:windir\system32\netstat.exe" -a -o -n 2>'' | Select-String -Pattern " .*[0-9\.]+:$($Port).*[0-9\.]+:[0-9]+ .*?([0-9]+)" -EA 0 } Catch { Write-Debug 'Failed to call netstat.exe.'; $netstat = $null } Foreach ($line in $netstat) { $processes += ($line -split ' {4,}')[-1] } $processes = $processes | Where-Object { $_ -gt 0 -and $_ -match '^\d+$' } | Sort-Object | Get-Unique if ($processes) { Foreach ($processId in $processes) { Write-Output "Process ID:$processId is using port $Port. Killing process." Try { Stop-Process -Id $processId -Force -Verbose -EA Stop } Catch { Write-Warning "There was an issue killing process: $processId" Write-Warning "This generally means that a 'protected application' is using this port." # TrayPort wraps within the 42000-42009 range. If a protected process holds # the current port, increment and wrap back to 42000 after 42009. $newPort = [int]$Port + 1 if ($newPort -gt 42009) { $newPort = 42000 } Write-Warning "Setting tray port to $newPort." New-ItemProperty -Path $Script:CWAARegistryRoot -Name TrayPort -PropertyType String -Value $newPort -Force -WhatIf:$False -Confirm:$False | Out-Null } } } } if ($PSCmdlet.ShouldProcess('LTService, LTSvcMon', 'Start Service')) { $Script:CWAAServiceNames | ForEach-Object { if (Get-Service $_ -EA 0) { Set-Service $_ -StartupType Automatic -EA 0 -Confirm:$False -WhatIf:$False $Null = & "$env:windir\system32\sc.exe" start "$($_)" 2>'' if ($LASTEXITCODE -ne 0) { Write-Warning "sc.exe start returned exit code $LASTEXITCODE for service '$_'." } $startedSvcCount++ Write-Debug "Executed Start Service for $($_)" } } # Wait for services if we issued start commands $stoppedServiceCount = ('LTService') | Get-Service -EA 0 | Where-Object { $_.Status -ne 'Running' } | Measure-Object | Select-Object -Expand Count if ($stoppedServiceCount -gt 0 -and $startedSvcCount -eq 2) { $timeout = New-TimeSpan -Minutes 1 $stopwatch = [Diagnostics.Stopwatch]::StartNew() Write-Verbose 'Waiting for services to start...' Do { Start-Sleep 2 $stoppedServiceCount = ('LTService') | Get-Service -EA 0 | Where-Object { $_.Status -ne 'Running' } | Measure-Object | Select-Object -Expand Count } Until ($stopwatch.Elapsed -gt $timeout -or $stoppedServiceCount -eq 0) $stopwatch.Stop() Write-Verbose 'Service start wait completed.' } # Report final state if ($stoppedServiceCount -eq 0) { Write-Output 'Services started successfully.' Write-CWAAEventLog -EventId 2000 -EntryType Information -Message 'Agent services started successfully.' $Null = Invoke-CWAACommand 'Send Status' -EA 0 -Confirm:$False } elseif ($startedSvcCount -gt 0) { Write-Output 'Service Start was issued but LTService has not reached Running state.' Write-CWAAEventLog -EventId 2001 -EntryType Warning -Message 'Agent services failed to reach Running state after start.' } else { Write-Output 'Service Start was not issued.' } } } Catch { Write-Error "There was an error starting the Automate agent services. $_" Write-CWAAEventLog -EventId 2002 -EntryType Error -Message "Agent service start failed. Error: $($_.Exception.Message)" } } End { Write-Debug "Exiting $($MyInvocation.InvocationName)" } } |