Stop and start service in-order on a remote server - powershell

I want to write a script to check 4 service on a server if they have status running when we stop them by order and start them on the other hand with delay.
First service must check that it is running and then start with others therefore we use delay.
$serverlist = Get-Content “.\server.txt”
$servicename4 = "Orbit Utveckling Consul"
$servicename3 = "Orbit Utveckling Identity"
$servicename2 = "Orbit Utveckling Service"
$servicename1 = "Orbit Utveckling Integration"
$delay = 60 # Ange i sekunder.
foreach ($server in $serverlist) {
$getservicestatus1 = Get-Service -Name $servicename1 -ComputerName $server
if ($getservicestatus1 -eq "Running") {
Set-Service -Name $servicename1 -ComputerName $server -Status stopped
Write-Host "$server $servicename1 Stoppat!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan $servicename2 stoppar..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus2 = (Get-Service -Name $servicename2 -ComputerName $server).status
if ($getservicestatus2 -eq "Running") {
Set-Service -Name $servicename2 -ComputerName $server -Status stopped
Write-Host "$server $servicename2 Stoppat!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server stoppar..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus3 = (Get-Service -Name $servicename3 -ComputerName $server).status
if ($getservicestatus3 -eq "Running") {
Set-Service -Name $servicename3 -ComputerName $server -Status stopped
Write-Host "$server $servicename3 Stoppat!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server stoppar..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus4 = (Get-Service -Name $servicename4 -ComputerName $server).status
if ($getservicestatus4 -eq "Running") {
Set-Service -Name $servicename4 -ComputerName $server -Status stopped
Write-Host "$server $servicename4 Stoppat!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server stoppar..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
}
# Filen startar tjänsten Drift_Cosmic på varje IX3a i txt-filen.
# Det görs med en delay på ett antal sekunder mellan varje start.
# Detta är en testfil tills dess att en riktig testkörning
# har gjorts i Drift.
Write-Host "$servicename4, $servicename3, $servicename2, $servicename1 startas med $delay sekunders mellanrum."
foreach ($server in $serverlist) {
# Skriv ut status på tjänsten i passande färg.
$getservicestatus4 = (Get-Service -Name $servicename4 -ComputerName $server).status
if ($getservicestatus4 -eq "Stopped") {
Set-Service -Name $servicename4 -ComputerName $server -Status Running
Write-Host "$server $servicename4 Startad!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server startas..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus3 = (Get-Service -Name $servicename3 -ComputerName $server).status
if ($getservicestatus3 -eq "Stopped") {
Set-Service -Name $servicename3 -ComputerName $server -Status Running
Write-Host "$server $servicename3 Startad!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server startas..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus2 = (Get-Service -Name $servicename2 -ComputerName $server).status
if ($getservicestatus2 -eq "Stopped") {
Set-Service -Name $servicename2 -ComputerName $server -Status Running
Write-Host "$server $servicename2 Startad!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server startas..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus1 = (Get-Service -Name $servicename1 -ComputerName $server).status
if ($getservicestatus1 -eq "Stopped") {
Set-Service -Name $servicename1 -ComputerName $server -Status Running
Write-Host "$server $servicename1 Startad!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server startas..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
}
Write-Host "." -ForegroundColor DarkBlue
Read-Host "Tryck ENTER för att avsluta"

You can configure service dependencies so that a service will only start/stop once its dependent services are also started/stopped.
Once you've done this you only need to stop service1 and Windows will deal with stopping the services dependencies... in order of their dependents.
You can see other services that have dependencies in Services. For example Fax service depends on Print Spooler, which itself depends on RPC, which then depends on DCOM
If manually stopped the Fax service, you'll see the GUI stop (in order) DCOM, RPC, Spooler then Fax.
Configuring dependencies only needs to be done once (per server):
sc config "service1" depend= "service2"
sc config "service2" depend= "service3"
sc config "service3" depend= "service4"
etc...
(There's no native Powershell command for doing this to my knowledge, I've only found sc.exe and using wmi, with sc being the simpler command.)
After this is setup you would only need a small bit of code to restart all the services in order:
$serverlist = Get-Content ".\server.txt"
foreach ($server in $serverlist) {
Get-Service -Name "service1" -ComputerName $server | Restart-Service
}

Related

Updating windows server remotely via Powershell

Hello I have been trying to make this script work for some time now, but I keep running into problems. The script is written with multiple servers in mind, although I am just testing it only on one test system for now.
Following I will post the script.
#List of Servers
$SQLServer = #('testserver.net')
$ApplicationServer = #('testserver.net')
$Servers = #($SQLServer, $ApplicationServer)
$ServiceName = #('tomcat9', 'MSSQLSERVER')
#Information Message
Write-Host "Starting update process for the following Servers:" $Servers "and Services:" $ServiceName
#Gets status of Servers
ForEach ($Index in $Servers)
{
Invoke-command {Get-Service tomcat9} -comp $Servers[$Index]
Invoke-command {Get-Service -Name 'MSSQLSERVER'} -comp $Servers[$Index]
}
#Information Message
Write-Host "Stopping the specified Services:" $ServiceName
#Stops services
#Sequentially stops TomCat and then DB Applications
ForEach ($Index in $Servers)
{
$ArrayService = Invoke-Command {Get-Service tomcat9} -comp $Servers[$Index]
if ($ArrayService.Status -ne "Stopped")
{
Invoke-Command {Stop-Service tomcat9} -comp $Servers[$Index]
}
$ArrayService = Invoke-Command {Get-Service -Name 'MSSQLSERVER'} -comp $Servers[$Index]
if ($ArrayService.Status -ne "Stopped")
{
Invoke-Command {Stop-Service -Name 'MSSQLSERVER'} -comp $Servers[$Index]
}
}
#Information Message
Write-Host "Will now start Windows Updates on servers and reboot"
#Will Update Windows, automatically reboot and out the log in the specified directory. This will be done to all listed Servers
ForEach ($Index in $Servers)
{
$Scriptblock = {
Invoke-WUJob -Comp $Servers[$Index] -RunNow -Confirm:$false -Verbose -Script {
Install-WindowsUpdate -MicrosoftUpdate -NotCategory "SilverLight" -NotTitle "Preview" -AcceptAll -AutoReboot | Out-File C:\PSWindowsUpdate.log
}
}
Invoke-Command -Comp $Servers[$Index] -ScriptBlock $Scriptblock
}
#Information Message
Write-Host "Starting up Services again"
#Starting SQL Server and checking if its running, if not running it will give more time before the Script continues
ForEach ($Index in $SQLServer)
{
$ArrayService = Invoke-Command {Get-Service -Name $ServiceName} -comp $SQLServer[$Index]
$FilteredService = $ArrayService | where {$_ -like 'MSQL'}
while ($FilteredService.Status -ne 'Running')
{
Invoke-Command {Start-Service $FilteredService} -comp $SQLServer[$Index]
Write-Host $FilteredService.Status
Write-Host "SQL Service starting on " $SQLServer[$Index]
function Check-Status
{
Start-Sleep -seconds 30
$FilteredService.Refresh()
if ($FilteredService.Status -eq 'Running')
{
Write-Host "SQL Service running"
#Invoke-Command {Start-Service $ArrayService | where {$_ -like 'tomcat9'}} -comp $ApplicationServer
}
else
{
Check-Status
}
}
}
}
#Starting TomCat Service again
ForEach ($Index in $ApplicationServer)
{
Write-Host "MUMService starting on " $ApplicationServer[$Index]
#Invoke-Command {Start-Service $ArrayService | where {$_ -like 'tomcat9'}} -comp $ApplicationServer[$Index]
$ServiceStatus = Invoke-Command {Get-Service tomcat9} -comp $ApplicationServer[$Index]
if ($ServiceStatus.Status -eq 'Running')
{
Invoke-Command {Start-Service $ArrayService | where {$_ -like 'tomcat9'}} -comp $ApplicationServer[$Index]
Write-Host "MUM Service running"
}
else
{
Invoke-Command {Start-Service $ArrayService | where {$_ -like 'tomcat9'}} -comp $ApplicationServer[$Index]
}
}
ForEach ($Index in $Servers)
{
invoke-command {Get-Service mum_software_tomcat9} -comp $Servers[$Index]
invoke-command {Get-Service -Name 'MSSQLSERVER'} -comp $Servers[$Index]
}
Either my logic is really wrong, or this doesnt work this way in powershell, but when I try to execute the script as is, there is an error for the parameter 'ComputerName'. It says that the argument is null or empty. Provide an argument that is not null or empty and then try the command again. Apparently it does not like $SQLServer[$Index].
The update functionality itself seems to work by itself though.
What is wrong with this?

Scanning For a Service on Online Devices with Powershell Script

I wrote a script to tell me if the SEP Master Service is running for all computer listed in a file, start the service if its stopped, and let me know if it doesn't exist. It's working, but when the script hits a computer that is not online, it slows down until an error is returned and then finally goes to the next computer in the list. Is there a way to only scan for the service on the deivces in the list that are online and can be pinged on the network?
$computers = Get-Content -Path "C:\temp2\ComputerList.txt"
foreach ($computer in $computers) {
$service = Get-Service -name SepMasterService -computername $computer
$ServiceStatus = $service.Status
$ServiceDisplayName = $service.DisplayName
if ($ServiceStatus -eq 'Running') {
Write-Output "Service OK - Status of $ServiceDisplayName is $ServiceStatus on $computer"
}
elseif ($ServiceStatus -eq 'stopped') {
Start-Service -Name SepMasterService -PassThru
}
else {
Write-Output "Symantec Endpoint Protection doesn't exist on $computer"
}
}
Add a check for online machines using the test-connection cmdlet and go to the next computer.
$computers = Get-Content -Path "C:\temp2\ComputerList.txt"
foreach ($computer in $computers) {
if(!(Test-Connection -ComputerName $computer -Count 1 -Quiet))
{
Write-Output "$computer is offline"
continue
}
$service = Get-Service -name SepMasterService -computername $computer
$ServiceStatus = $service.Status
$ServiceDisplayName = $service.DisplayName
if ($ServiceStatus -eq 'Running') {
Write-Output "Service OK - Status of $ServiceDisplayName is $ServiceStatus on $computer"
}
elseif ($ServiceStatus -eq 'stopped') {
Start-Service -Name SepMasterService -PassThru
}
else {
Write-Output "Symantec Endpoint Protection doesn't exist on $computer"
}
}
The -Count parameter specifies how many time to ping the computer. The default is 4 but this will speed up your process. The continue statement will stop executing any of the code in the current iteration of the foreach loop and go to the next computer.
Hope this helps.

Getting error in my script

I keep getting an error message stating
"Exception calling "Start" with "0" argument(s): "Cannot start service RTCRGS on computer 'CORPxxxxxxx.xxxx.net'."
At line:25 char:18
+ $_.Start <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException"
Any suggestion on why this happens and how to fix it?
$services = "RTCRGS"
$SvrName = 'CORPxxxx.xxxx.xxxx'
Get-Service -ComputerName $SvrName -Name $services | % {
Write-host "$($_.Name) on $SvrName is $($_.Status)"
if ($_.Status -eq 'stopped') {
Write-Host "Starting $($_.Name) in 5 sec..."
Start-Sleep 5
Write-Host "$($_.Name) is Starting, please wait..."
$_.Start()
Write-Host "Checking status of service, please wait for 25 sec..."
Start-Sleep 20
Write-Host "$($_.Name) on $SvrName is $($_.Status)"
} elseif ($_.Status -eq 'running') {
Write-Host "Restaring $($_.Name) in 5 sec..."
Start-Sleep 5
$_.Stop()
Start-Sleep 5
Write-Host "$($_.Name) is Starting, please wait..."
$_.Start()
Write-Host "Checking status of service, please wait for 25 sec..."
Start-Sleep 25
Write-Host "$($_.Name) on $SvrName is $($_.Status)"
}
}
If the service is NOT disabled (and you have checked you can restart it manually) you might be better of with something like this
$services = "RTCRGS"
$SvrName = 'CORPxxxx.xxxx.xxxx'
Get-Service -ComputerName $SvrName -Name $services | ForEach-Object {
Write-host "$($_.Name) on $SvrName is $($_.Status)"
if (#("Stopped","StopPending","Paused","PausePending") -contains $_.Status) {
Write-Host "Starting service $($_.Name), please wait..."
$_.Start()
}
else {
Write-Host "Stopping service $($_.Name)..."
$_.Stop()
# as HAL9256 suggested, perform a loop to see if service has really stopped
do {
# recheck the ACTUAL status, not the status you captured before
$newStatus = (Get-Service -ComputerName $SvrName -Name $_.Name).Status
} while ($newStatus -ne "Stopped")
Write-Host "$($_.Name) is Restarting, please wait..."
$_.Start()
}
Write-Host "Checking status of service, please wait for 25 sec..."
Start-Sleep 25
# here again you should recheck the ACTUAL status, not the status you captured before
$newStatus = (Get-Service -ComputerName $SvrName -Name $_.Name).Status
Write-Host "$($_.Name) on $SvrName is $newStatus"
}
You can read the possible values for 'Status' here

Waitforstatus service powershell

I have written a script to stop the services on any server!
But I get error:
YMethod invocation failed because[System.ServiceProcess.ServiceControllerStatus] does not contain a method named 'WaitForStatus'.
At C:\Admin\Scripts\JBoss_StartStopp\stoppa_alla_IX2 och IX3.ps1:18 char:7
+ $getservicestatus.WaitForStatus("Stopped")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
When you quit a service on a server, I want to wait until the service is stopped and then go to the next service on the next server!
$serverlist = Get-Content “.\server.txt”
$servicename = "JBoss_cambio"
$serverlistIX3 = Get-Content “.\ix3.txt”
$servicenameIX3 = "Laskopia_Cosmic"
foreach ($server in $serverlist) {
$getservicestatus = (Get-Service -Name $servicename -ComputerName $server).status
if ($getservicestatus -eq "Running") {
Set-Service -Name $servicename -ComputerName $server -Status Stopped
$getservicestatusIX3.WaitForStatus("Stopped")
Write-Host "$server $servicename Stoppad!" -ForegroundColor Green
}
else
{
Write-Host "$server $servicename var redan Stopped!" -ForegroundColor Yellow
}
}
foreach ($server in $serverlistIX3) {
$getservicestatusIX3 = (Get-Service -Name $servicenameIX3 -ComputerName $server).status
if ($getservicestatusIX3 -eq "Running") {
Set-Service -Name $servicenameIX3 -ComputerName $server -Status Stopped
$getservicestatusIX3.WaitForStatus("Stopped")
Write-Host "$server $servicenameIX3 Sttopad!" -ForegroundColor Green
}
else
{
Write-Host "$server $servicenameIX3 var redan Stoppad!" -ForegroundColor Yellow
}
}
Write-Host "." -ForegroundColor DarkBlue
Read-Host "Tryck ENTER för att avsluta"
The WaitForStatus method is member of System.ServiceProcess.ServiceController class, not ServiceControllerStatus. For example:
$s = Get-Service spooler
$s.WaitForStatus("Stopped")
You could modify your code to something like this:
$serviceIX3 = Get-Service -Name $servicenameIX3 -ComputerName $server
if($serviceIX3.status -eq "Running") {
Stop-Service $serviceIX3
$serviceIX3.WaitForStatus("Stopped")
Write-Host "$server $servicenameIX3 Sttopad!" -ForegroundColor Green
}
Your $getservicestatus is a System.ServiceProcess.ServiceControllerStatus and not a ServiceController object.
This getservicestatus doesn't have WaitForStatus method.
Try this
$getservice = Get-Service -Name $servicename -ComputerName $server
And now you can use $getservices.WaitForStatus("Stopped")
Write-Output "We stop the service: $servicename"
Stop-Service -Name $servicename
$getservice.WaitForStatus("Stopped")
Write-Output "$servicename Stoped"
Unless you use a time-span parameter, wait will continually test every 1/4 second or so and may inadvertently wait forever.

powershell service if scripts

I am trying to right a script to check if a services is running on one of our servers if the services are running just write an event log, but if the services are stopped run another script outside of this script. I am running to issues with verifying if the services are running. I am sure it's simple but I am not that proficient in if statements. Any help is much appreciated.
# Service Status
$Service='Spooler'
# Check service
((get-service $service).Status -eq 'Running')
$Service2='VMTools'
((get-service $service2).Status -eq 'Running')
Execute Restarting Script if Stopped Service
{
if ($service.Status -eq 'Stopped')
$service = False
{
elseif($Service2.Status -eq 'Stopped')
"$service2 = False"
}
else {
Z:\SeviceRestart.ps1
} } Write-EventLog -LogName "Service_TestScript" -Source
"Service_TestScript" -EventId 1 -Message "Verified $service ,
$service2 are running"
My script now
Service Status
$Service='Ipswitch SSH Server'
$Service2='Ipswitch WS_FTP Server'
function RestartServiceIfStopped([string]$service) {
$serviceStatus = (Get-Service $service).Status
if ($serviceStatus -eq 'Stopped'){
Start-Service -displayname $service
Write-Host "Started $service"
}
elseif ($serviceStatus -eq 'Running'){
Write-Host "Service $service is running"
}
Write-EventLog -logname application -source MyApplication -eventid 1 -message "$service is running" }
$hostname = 'FTP02'
$smtpServer = '####'
function SendMailMessageIFStopped([string]$service)
{
$serviceStatus = (Get-Service $service).Status
if ($serviceStatus -eq 'Stopped'){
Send-MailMessage -To '####' -Subject "Restarting Printspooler Service on $hostname" -Body "This is an automated message
to confirm that the $Service , $Service2 service on $hostname
is about to be restarted as part of failure, after recieving this message please check system to confirm." -From
test#test.com -SmtpServer $smtpServer } }
RestartServiceIfStopped "Ipswitch SSH Server"
RestartServiceIfStopped 'Ipswitch WS_FTP Server'
Write-EventLog -Entrytype Warning -LogName "Service_TestScript"
-Source "Service_TestScript" -EventId 1 -Message "Verified $service , $service2 are running"
You can simplify your script
function RestartServiceIfStopped([string]$service)
{
$serviceStatus = (Get-Service $service).Status
if ($serviceStatus -eq 'Stopped'){
Start-Service -displayname $service
Write-Host "Started $service"
}
elseif ($serviceStatus -eq 'Running'){
Write-Host "Service $service is running"
}
#Write-EventLog -logname application -source MyApplication -eventid 1 -message "$service is running"
}
RestartServiceIfStopped "Spooler"
For EventLog, you will have to create an event source using New-EventLog cmdlet (once per host).
Figured it out I had to put the Send-MailMessage under the first IF-statement
Thank you for your help Punit Ganshani MVP
Service Status
$Service='Print Spooler' $Service2='VMTools' $hostname = 'FTP02'
$smtpServer = '****'
function RestartServiceIfStopped([string]$service) {
$serviceStatus = (Get-Service $service).Status
if ($serviceStatus -eq 'Stopped'){
Start-Service -displayname $service
Write-Host "Started $service"
Send-MailMessage -To 'test#test.com,' -Subject
"Restarting $service and $service2 Service on $hostname" -Body "This
is an automated message to confirm that the $Service , $Service2
service on $hostname is about to be restarted as part of failure,
after recieving this message please check system to confirm." -From
-SmtpServer $smtpServer
}
elseif ($serviceStatus -eq 'Running'){
Write-Host "Service $service is running"
}
{
$serviceStatus = (Get-Service $service2).Status
if ($serviceStatus -eq 'Stopped'){
Start-Service -displayname $service2
Write-Host "Started $service2"
}
elseif ($serviceStatus -eq 'Running'){
Write-Host "Service $service2 is running"
} } } RestartServiceIfStopped "Print Spooler" RestartServiceIfStopped 'VMTools'
Write-EventLog -Entrytype Warning -LogName "Service_TestScript"
-Source "Service_TestScript" -EventId 1 -Message "Verified $service , $service2 are running"