windows - run - ¿Cómo verificar si un servicio se está ejecutando a través de un archivo por lotes e iniciarlo, si no se está ejecutando?
task scheduler restart service (12)
Quiero escribir un archivo por lotes que realice las siguientes operaciones:
- Verifica si un servicio se está ejecutando
- Si se está ejecutando, salga del lote
- Si no se está ejecutando, inicie el servicio
Las muestras de código que busqué en Google hasta ahora resultaron no funcionar, así que decidí no publicarlas.
El inicio de un servicio se realiza mediante:
net start "SERVICENAME"
- ¿Cómo puedo verificar si un servicio se está ejecutando y cómo hacer una declaración if en un archivo por lotes?
- Estoy un poco confundido. ¿Cuál es el argumento que tengo que pasar al inicio neto? El nombre del servicio o su nombre para mostrar?
Acabo de encontrar este hilo y quería agregar a la discusión si la persona no quiere usar un archivo por lotes para reiniciar los servicios. En Windows hay una opción si va a Servicios, propiedades del servicio y luego a recuperación. Aquí puede establecer parámetros para el servicio. Me gusta reiniciar el servicio si el servicio se detiene. Además, incluso puede hacer que un segundo intento fallido haga algo diferente al reiniciar la computadora.
Cuando se usa Windows en Español, el código debe quedar asi (cuando se usa Windows en español, el código es):
for /F "tokens=3 delims=: " %%H in (''sc query MYSERVICE ^| findstr " ESTADO"'') do (
if /I "%%H" NEQ "RUNNING" (
REM Put your code you want to execute here
REM For example, the following line
net start MYSERVICE
)
)
Reemplazar MYSERVICE con el nombre del servicio que se desea procesar. Puedes ver el nombre del servicio viendo las propiedades del servicio. (Reemplace MYSERVICE con el nombre del servicio que se procesará. Puede ver el nombre del servicio en las propiedades del servicio).
Deberias hacer eso:
FOR %%a IN (%Svcs%) DO (SC query %%a | FIND /i "RUNNING"
IF ERRORLEVEL 1 SC start %%a)
Iniciando el servicio usando la secuencia de comandos de Powershell. Puede vincular esto al planificador de tareas y activarlo en intervalos o según sea necesario. Cree esto como un archivo PS1, es decir, archivo con la extensión PS1 y luego permita que este archivo se desencadene desde el programador de tareas.
Para iniciar el servicio de parada
en el programador de tareas si lo está usando en el servidor, use esto en argumentos
-noprofile -executionpolicy bypass -file "C: / Service Restart Scripts / StopService.PS1"
verificar ejecutando el mismo en cmd si funciona debería funcionar en el programador de tareas también
$Password = "Enter_Your_Password"
$UserAccount = "Enter_Your_AccountInfor"
$MachineName = "Enter_Your_Machine_Name"
$ServiceList = @("test.SocketService","test.WcfServices","testDesktopService","testService")
$PasswordSecure = $Password | ConvertTo-SecureString -AsPlainText -Force
$Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $UserAccount, $PasswordSecure
$LogStartTime = Get-Date -Format "MM-dd-yyyy hh:mm:ss tt"
$FileDateTimeStamp = Get-Date -Format "MM-dd-yyyy_hh"
$LogFileName = "C:/Users/krakhil/Desktop/Powershell/Logs/StartService_$FileDateTimeStamp.txt"
#code to start the service
"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"###################### STARTING SERVICE ##########################" >> $LogFileName
for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName
Write-Output "`n####################################"
Write-Output "Starting Service - " $ServiceList[$i]
"$LogStartTime => Starting Service: $ServiceName" >> $LogFileName
Start-Service $ServiceList[$i]
$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}
if($ServiceState.Status -eq "Running")
{
"$LogStartTime => Started Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Started Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`n Service didn''t Start. Current State is - "
Write-Host $ServiceState.Status
}
}
#code to stop the service
"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"###################### STOPPING SERVICE ##########################" >> $LogFileName
for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName
Write-Output "`n####################################"
Write-Output "Stopping Service - " $ServiceList[$i]
"$LogStartTime => Stopping Service: $ServiceName" >> $LogFileName
Stop-Service $ServiceList[$i]
$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}
if($ServiceState.Status -eq "Stopped")
{
"$LogStartTime => Stopped Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Stopped Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`nService didn''t Stop. Current State is - "
Write-Host $ServiceState.Status
}
}
Para alternar un servicio, use lo siguiente;
NET START "Coordinador de transacciones distribuidas" || NET STOP "Coordinador de transacciones distribuidas"
Para verificar el estado de un servicio, use la sc query <SERVICE_NAME>
. Para los bloques en los archivos por lotes, verifique la documentación .
El siguiente código verificará el estado del servicio MyServiceName
y lo iniciará si no se está ejecutando (el bloque if se ejecutará si el servicio no se está ejecutando):
for /F "tokens=3 delims=: " %%H in (''sc query "MyServiceName" ^| findstr " STATE"'') do (
if /I "%%H" NEQ "RUNNING" (
REM Put your code you want to execute here
REM For example, the following line
net start "MyServiceName"
)
)
Explicación de lo que hace:
- Consulta las propiedades del servicio.
- Busca la línea que contiene el texto "ESTADO"
- Tokeniza esa línea y saca el tercer token, que es el que contiene el estado del servicio.
- Comprueba el estado resultante contra la cadena "RUNNING"
En cuanto a su segunda pregunta, el argumento que querrá pasar al net start
es el nombre del servicio, no el nombre para mostrar.
Puede usar el siguiente comando para ver si un servicio se está ejecutando o no:
sc query [ServiceName] | findstr /i "STATE"
Cuando lo ejecuto para mi NOD32 Antivirus, obtengo:
STATE : 4 RUNNING
Si se detuvo, obtendría:
STATE : 1 STOPPED
Puede usar esto en una variable para luego determinar si usa NET START o no.
El nombre del servicio debe ser el nombre del servicio, no el nombre para mostrar.
Relacionado con la respuesta de @DanielSerrano, me han mordido recientemente por la localización del comando sc.exe
, concretamente en español. Mi propuesta es señalar la línea y el token que contiene el estado del servicio numérico e interpretarlo, que debería ser mucho más robusto:
@echo off
rem TODO: change to the desired service name
set TARGET_SERVICE=w32time
set SERVICE_STATE=
rem Surgically target third line, as some locales (such as Spanish) translated the utility''s output
for /F "skip=3 tokens=3" %%i in (''""%windir%/system32/sc.exe" query "%TARGET_SERVICE%" 2>nul"'') do (
if not defined SERVICE_STATE set SERVICE_STATE=%%i
)
rem Process result
if not defined SERVICE_STATE (
echo ERROR: could not obtain service state!
) else (
rem NOTE: values correspond to "SERVICE_STATUS.dwCurrentState"
rem https://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx
if not %SERVICE_STATE%==4 (
echo WARNING: service is not running
rem TODO: perform desired operation
rem net start "%TARGET_SERVICE%"
) else (
echo INFORMATION: service is running
)
)
Probado con:
- Windows XP (32 bits) Inglés
- Windows 10 (32 bits) español
- Windows 10 (64 bit) Inglés
También quería un correo electrónico enviado si el servicio se inició de esta manera, así que agregué un poco al código @Ic, pensé que lo publicaría en caso de que ayudara a alguien. Utilicé SendMail pero hay otras opciones de línea de comandos. ¿Cómo enviar un correo electrónico simple desde un archivo por lotes de Windows?
set service=MyServiceName
for /F "tokens=3 delims=: " %%H in (''sc query %service% ^| findstr " STATE"'') do (
if /I "%%H" NEQ "RUNNING" (
net start %service%
for /F "tokens=3 delims=: " %%H in (''sc query %service% ^| findstr " STATE"'') do (
if /I "%%H" EQ "RUNNING" (
SendMail /smtpserver localhost /to [email protected] /from [email protected] /subject Service Autostart Notification /body Autostart on service %service% succeded.
) else (
SendMail /smtpserver localhost /to [email protected] /from [email protected] /subject Service Autostart Notification /body Autostart on service %service% failed.
)
)
)
)
Versión independiente del lenguaje.
@Echo Off
Set ServiceName=Jenkins
SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
echo %ServiceName% not running
echo Start %ServiceName%
Net start "%ServiceName%">nul||(
Echo "%ServiceName%" wont start
exit /b 1
)
echo "%ServiceName%" started
exit /b 0
)||(
echo "%ServiceName%" working
exit /b 0
)
@Echo off
Set ServiceName=wampapache64
SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
echo %ServiceName% not running
echo
Net start "%ServiceName%"
SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
Echo "%ServiceName%" wont start
)
echo "%ServiceName%" started
)||(
echo "%ServiceName%" was working and stopping
echo
Net stop "%ServiceName%"
)
pause
@echo off
color 1F
@sc query >%COMPUTERNAME%_START.TXT
find /I "AcPrfMgrSvc" %COMPUTERNAME%_START.TXT >nul
IF ERRORLEVEL 0 EXIT
IF ERRORLEVEL 1 NET START "AcPrfMgrSvc"