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.
Related
when executing my script I am getting an Error that I do not quite understand. It tells me that there is a validation error.
I have tested out some different variations but it keeps coming down to the same error.
ForEach ($Index in $SQLServer)
{
$ServiceStatus = Invoke-Command {Get-Service 'MSSQLSERVER'} -comp $Index
while ($FilteredService.Status -ne 'Running')
{
Invoke-Command {Start-Service $ServiceStatus} -comp $Index
Write-Host $ServiceStatus.Status
Write-Host "SQL Service starting on " $Index
function Check-Status
{
Start-Sleep -seconds 30
$ServiceStatus.Refresh()
if ($ServiceStatus.Status -eq 'Running')
{
Write-Host "SQL Service running"
}
else
{
Check-Status
}
}
}
}
The error is like this:
Cannot validate argument on parameter 'InputObject'.The argument is null or empty. Provide an arguemnt that is not null or empty, and then try the command again.
+ CategoryInfo : InvalidData: (:) [Start-Service], ParameterBindingValidationException
+ FullyQualifiedErrorId: ParameterArgumentValidationError...
Normally this error occurs once some parameter has not been initialized yet , but I just cant figure out which one that is. Any help would be appreciated.
EDIT:
ForEach ($Index in $SQLServer)
{
$ArrayService = Invoke-Command {Get-Service -Name 'MSSQLSERVER'} -comp $Index
if ($ArrayService.Status -ne 'Running')
{
Invoke-Command {Start-Service $script:ArrayService} -comp $Index
Write-Host $ArrayService.Status
Write-Host "SQL Service starting on " $Index
function Check-Status
{
Start-Sleep -seconds 30
$ArrayService.Refresh()
if ($ArrayService.Status -eq 'Running')
{
Write-Host "SQL Service running"
}
else
{
Check-Status
}
Check-Status
}
}
}
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?
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.
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
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
}