First post! I apologize in advance for formatting. I'm just getting familiar with PowerShell and I'm wanting to Stop a service first, restart another service, and start the initial service. Before moving onto the next next service, I want to make sure that the service has stopped before proceeding.
I'm using this function that was mentioned here and tried to tailor it for my code.
Workflow Goal:
- Stop Service A
- Restart Service B
- Start Service A
Code:
#Stops Service A and validates its in "Stopped" status
Get-Service 'ServiceNameA' -ComputerName 'ExampleServerA' | Stop-Service -force -PassThru
function WaitUntilServices1($searchString, $status)
{
# Get all services where DisplayName matches $searchString and loop through each of them.
foreach($service in (Get-Service -DisplayName $searchString))
{
# Wait for the service to reach the $status or a maximum of 30 seconds
$service.WaitForStatus($status, '00:00:30')
}
}
WaitUntilServices1 "ServiceDisplayNameA" "Stopped"
#Restarts Service B and validates its in "Running" status
Get-Service 'ServiceNameB' -ComputerName 'ExampleServerB' | Restart-Service -force -PassThru
function WaitUntilServices2($searchString, $status)
{
# Get all services where DisplayName matches $searchString and loop through each of them.
foreach($service in (Get-Service -DisplayName $searchString))
{
# Wait for the service to reach the $status or a maximum of 30 seconds
$service.WaitForStatus($status, '00:00:30')
}
}
WaitUntilServices2 "ServiceDisplayNameB" "Running"
#Start Service A and validates its in "Running" status
Get-Service 'ServiceA' -ComputerName 'ExampleServerA' | Start-Service -force -PassThru
Read-Host -Prompt "Press Enter to exit"
The Code I have above is giving me the following Errors for both of the functions.
Exception calling "WaitForStatus" with "2" argument(s): "Time out has expired and the operation has not been completed." At C:\PowerShell\ScriptExample\ScriptExampleFix.ps1:10 char:9
$service.WaitForStatus($status, '00:00:30')
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : TimeoutException
Then for the very last portion to start the service I'm getting 1 more error:
Start-Service : A parameter cannot be found that matches parameter name 'force'. At C:\PowerShell\ScriptExample\ScriptExampleFix.ps1:32 char:85
... erName 'ServerNameExample' | Start-Service -force -PassTh ...
~~~~~~
CategoryInfo : InvalidArgument: (:) [Start-Service], ParameterBindingException
FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.StartServiceCommand
Any help would get greatly appreciated :)
CodePudding user response:
In the first statement:
#Stops Service A and validates its in "Stopped" status
Get-Service 'ServiceNameA' -ComputerName 'ExampleServerA' | Stop-Service -force -PassThru
You ask PowerShell to stop ServiceNameA
on a remote computer.
You then call WaitUntilServices1
which attempts to wait for a service of the same name on your local computer - which is obviously not gonna stop any time soon because you requested stopping a service on a different computer.
Change the function definition to accept a -ComputerName
parameter too and pass that to Get-Service
:
function Wait-ServiceStatus {
param(
[string]$Name,
[string]$ComputerName = $('.'),
[System.ServiceProcess.ServiceControllerStatus]$Status
)
foreach($service in Get-Service -Name $Name -ComputerName $ComputerName){
# If any call to WaitForStatus times out and throws, return $false
try { $service.WaitForStatus($Status, '00:00:30') } catch { return $false }
}
# No errors thrown while waiting, all is good, return $true
return $true
}
Now we can do:
# request the remote SCM stop the service
Get-Service 'ServiceNameA' -ComputerName 'ExampleServerA' | Stop-Service -Force
$success = Wait-ServiceStatus -Name 'ServiceNameA' -ComputerName 'ExampleServerA' -Status Stopped
if(-not $success){
# output an error
Write-Error "failed to complete restart cycle, 'ServiceNameA' on 'ExampleServerA' failed to stop in a timely manner"
# return from this script/function for good measure
return
}
# ... if we've reached this point the wait must have been successful, continue with the restart cycle.
Get-Service 'ServiceNameB' -ComputerName 'ExampleServerB' | Restart-Service -force -PassThru
$success = Wait-ServiceStatus -Name 'ServiceNameB' -ComputerName 'ExampleServerB' -Status Running
if(-not $success){
# ... etc.
}