¿Detener e iniciar un servicio a través de un archivo por lotes o cmd?

288

¿Cómo puedo escribir un bat o cmd para detener e iniciar un servicio de manera confiable con la comprobación de errores (o informarme que no fue exitoso por alguna razón)?

Keng
fuente
Tal vez sea algo fuera del tema (ya que solicita instrucciones de bat y cmd) pero: PowerShell le brinda mucho control y comentarios para realizar acciones como esta.
GvS

Respuestas:

347

Use el SCcomando (control de servicio), le brinda muchas más opciones que solo start& stop.

  DESCRIPCIÓN:
          SC es un programa de línea de comando utilizado para comunicarse con el
          NT Service Controller y servicios.
  USO:
      sc <servidor> [comando] [nombre del servicio] ...

      La opción <server> tiene la forma "\\ ServerName"
      Puede obtener más ayuda sobre los comandos escribiendo: "sc [comando]"
      Comandos:
        consulta ----------- Consulta el estado de un servicio, o
                        enumera el estado de los tipos de servicios.
        queryex --------- Consulta el estado extendido de un servicio, o
                        enumera el estado de los tipos de servicios.
        inicio ----------- Inicia un servicio.
        pausa ----------- Envía una solicitud de control PAUSE a un servicio.
        interrogar ----- Envía una solicitud de control INTERROGATE a un servicio.
        continuar -------- Envía una solicitud de control CONTINUAR a un servicio.
        stop ------------ Envía una solicitud STOP a un servicio.
        config ---------- Cambia la configuración de un servicio (persistente).
        description ----- Cambia la descripción de un servicio.
        falla --------- Cambia las acciones tomadas por un servicio en caso de falla.
        qc -------------- Consulta la información de configuración de un servicio.
        qdescription ---- Consulta la descripción de un servicio.
        qfailure -------- Consulta las acciones tomadas por un servicio en caso de falla.
        eliminar ---------- Elimina un servicio (del registro).
        crear ---------- Crea un servicio. (lo agrega al registro).
        control --------- Envía un control a un servicio.
        sdshow ---------- Muestra el descriptor de seguridad de un servicio.
        sdset ----------- Establece el descriptor de seguridad de un servicio.
        GetDisplayName: obtiene el DisplayName para un servicio.
        GetKeyName ------ Obtiene ServiceKeyName para un servicio.
        EnumDepend ------ Enumera las dependencias de servicio.

      Los siguientes comandos no requieren un nombre de servicio:
      sc <servidor> <comando> <opción>
        boot ------------ (ok | bad) Indica si el último arranque debería
                        guardarse como la última configuración de arranque válida conocida
        Bloquear ------------ Bloquea la base de datos del servicio
        QueryLock ------- Consulta el LockStatus para la base de datos SCManager
  EJEMPLO:
          sc iniciar MyService
Ferruccio
fuente
1
Estoy de acuerdo en que esto es mejor que net start / stop. Tenga en cuenta que también hay una opción para tocar servicios en máquinas remotas.
Outlaw Programmer
1
Gran respuesta. Pero debe ser administrador para ejecutar el 'servicio de inicio SC'. Encontré una solución para eso aquí . (La respuesta aceptada contiene la solución)
Michael K.
56
El problema con SC es que el comando regresa inmediatamente y no después de que se completa la acción. Si desea reiniciar un servicio a través de un archivo por lotes (detener y luego iniciar), la detención regresa inmediatamente, el inicio falla porque el servicio no se detiene. Net stop / start regresa después de que se completa la acción, por lo que no tiene este problema.
Dom
Abrí el cmd como modo de administrador, obteniendo un error La sintaxis de este comando es: servicio NET STOP
Satish Singh
¿Hay alguna manera de verificar si el servicio se detiene correctamente? en 2020?
Anand Varkey Philips
212
net start [serviceName]

y

net stop [serviceName]

decirle si han tenido éxito o fallado con bastante claridad. Por ejemplo

U:\>net stop alerter
The Alerter service is not started.

More help is available by typing NET HELPMSG 3521.

Si se ejecuta desde un archivo por lotes, tiene acceso al ERRORLEVEL del código de retorno. 0 indica éxito. Cualquier cosa más alta indica fracaso.

Como un archivo bat error.bat:

@echo off
net stop alerter
if ERRORLEVEL 1 goto error
exit
:error
echo There was a problem
pause

El resultado se ve así:

U:\>error.bat
The Alerter service is not started.

More help is available by typing NET HELPMSG 3521.

There was a problem
Press any key to continue . . .

Códigos de retorno

 - 0 = Success
 - 1 = Not Supported
 - 2 = Access Denied
 - 3 = Dependent Services Running
 - 4 = Invalid Service Control
 - 5 = Service Cannot Accept Control
 - 6 = Service Not Active
 - 7 = Service Request Timeout
 - 8 = Unknown Failure
 - 9 = Path Not Found
 - 10 = Service Already Running
 - 11 = Service Database Locked
 - 12 = Service Dependency Deleted
 - 13 = Service Dependency Failure
 - 14 = Service Disabled
 - 15 = Service Logon Failure
 - 16 = Service Marked For Deletion
 - 17 = Service No Thread
 - 18 = Status Circular Dependency
 - 19 = Status Duplicate Name
 - 20 = Status Invalid Name
 - 21 = Status Invalid Parameter 
 - 22 = Status Invalid Service Account
 - 23 = Status Service Exists
 - 24 = Service Already Paused

Editar 20.04.2015

Códigos de retorno:

El comando NET no devuelve los códigos de retorno documentados de la clase Win32_Service (Servicio no activo, Tiempo de espera de solicitud de servicio, etc.) y para muchos errores simplemente devolverá Errorlevel 2.

Mire aquí: http://ss64.com/nt/net_service.html

Bill Michell
fuente
1
NET no es solo para funciones relacionadas con el servicio, mientras que SC es solo para funciones relacionadas con el servicio.
Wernight
3
Esta respuesta es mejor porque el comando "net" bloquea y espera a que el servicio se inicie o pare antes de que el script por lotes continúe ejecutándose.
Steven
Como (como dice Edit) la mayoría de las veces el resultado errorleveldevuelto es 2, vea aquí cómo interpretar el resultado del error .
HeyJude
28

Puede usar el comando NET START y luego verificar la variable de entorno ERRORLEVEL, p. Ej.

net start [your service]
if %errorlevel% == 2 echo Could not start service.
if %errorlevel% == 0 echo Service started successfully.
echo Errorlevel: %errorlevel%

Descargo de responsabilidad: he escrito esto desde la parte superior de mi cabeza, pero creo que funcionará.

Jonas Gulle
fuente
8

En lugar de verificar códigos, esto también funciona

net start "Apache tomcat" || goto ExitError

:End  
exit 0  

:ExitError  
echo An error has occurred while starting the tomcat services  
exit 1  
vanval
fuente
7

He creado mi archivo por lotes personal para esto, el mío es un poco diferente, pero puede modificarlo como mejor le parezca. Creé esto hace un tiempo porque estaba aburrido y quería hacer una manera simple para que las personas pudieran ingresar el final, el inicio, la detención o la configuración en automático. Este archivo BAT simplemente le solicita que ingrese el nombre del servicio y hará el resto por usted. No me di cuenta de que estaba buscando algo que indicara algún error, debo haber leído mal esa parte. Aunque normalmente esto se puede hacer ingresando >> output.txt al final de la línea.

El% var% es solo una forma para que el usuario pueda ingresar su propio servicio en este, en lugar de tener que modificar el archivo bat cada vez que desee iniciar / detener un servicio diferente.

Si me equivoco, cualquiera puede sentirse libre de corregirme al respecto.

@echo off
set /p c= Would you like to start a service [Y/N]?
  if /I "%c%" EQU "Y" goto :1
  if /I "%c%" EQU "N" goto :2
    :1  
    set /p var= Service name: 
:2 
set /p c= Would you like to stop a service [Y/N]?
  if /I "%c%" EQU "Y" goto :3
  if /I "%c%" EQU "N" goto :4
    :3  
    set /p var1= Service name:
:4
set /p c= Would you like to disable a service [Y/N]?
  if /I "%c%" EQU "Y" goto :5
  if /I "%c%" EQU "N" goto :6
    :5  
    set /p var2= Service name:
:6 
set /p c= Would you like to set a service to auto [Y/N]?
  if /I "%c%" EQU "Y" goto :7
  if /I "%c%" EQU "N" goto :10
    :7  
    set /p var3= Service name:
:10
sc start %var%
sc stop %var1%
sc config %var2% start=disabled
sc config %var3% start=auto
Nathanial Wilson
fuente
1
Por lo general, las respuestas de solo código no son apreciadas. ¿Podría dar más detalles sobre su solución o agregar algunos comentarios explicativos?
una tijereta
2
Creé esto hace un tiempo porque estaba aburrido y quería hacer una manera simple para que las personas puedan ingresar el final, el inicio, la detención o la configuración en automático. Este archivo BAT simplemente solicita que ingrese el nombre del servicio y hará el resto por usted.
Nathanial Wilson
6

Usar los códigos de retorno de net starty me net stopparece el mejor método. Pruebe esto: los códigos de retorno de Net Start .

ZombiOvejas
fuente
2
La página vinculada ya no existe. Como tal, esto es más un comentario ahora.
Neolisco el
5

La sintaxis siempre me atrapa ... así que ...

Aquí se explica explícitamente cómo agregar una línea a un archivo por lotes que eliminará un servicio remoto (en otra máquina) si es administrador en ambas máquinas, ejecute .bat como administrador y las máquinas estén en el mismo dominio. El nombre de la máquina sigue el formato UNC \ myserver

sc \\ip.ip.ip.ip stop p4_1

En este caso ... p4_1 era tanto el Nombre del servicio como el Nombre para mostrar, cuando ve las Propiedades del servicio en el Administrador de servicios. Debe usar el nombre del servicio.

Para sus adictos a Service Ops ... ¡asegúrese de agregar su código de razón y comentar! es decir, '4' que equivale a 'Planificado' y comentar 'Detener el servidor por mantenimiento'

sc \\ip.ip.ip.ip stop p4_1 4 Stopping server for maintenance
ATSiem
fuente
1
¿Cómo hago esto si necesito usar otro ID de usuario y contraseña para iniciar sesión?
Frantumn
1
Ejecutas CMDcomo el otro usuario / ID y runas /user:Domain\UserName cmdluego ingresas tu contraseña. CMD comenzará a ejecutarse como la cuenta de usuario especificada.
user4317867
4

Nos gustaría pensar que "net stop" detendrá el servicio. Lamentablemente, la realidad no es tan en blanco y negro. Si el servicio tarda mucho en detenerse, el comando volverá antes de que se detenga. Sin embargo, no lo sabrá, a menos que marque el nivel de error.

La solución parece ser recorrer todo el ciclo buscando el estado del servicio hasta que se detenga, con una pausa cada vez que se completa el ciclo.

Pero entonces de nuevo...

Estoy viendo que el primer servicio tarda mucho en detenerse, luego la "parada neta" para un servicio posterior parece no hacer nada. Mire el servicio en el administrador de servicios, y su estado todavía está "Iniciado", sin cambios en "Deteniendo". Sin embargo, puedo detener este segundo servicio manualmente usando el SCM, y se detiene en 3 o 4 segundos.

DaveH
fuente
3

o puede iniciar el servicio remoto con este cmd: sc \\<computer> start <service>

onionpsia
fuente
3

Acabo de usar el ejemplo anterior de Jonas y creé una lista completa de 0 a 24 niveles de error. Otra publicación es correcta net starty net stopsolo usa errorlevel0 para el éxito y 2 para el fracaso.

Pero esto es lo que funcionó para mí:

net stop postgresql-9.1
if %errorlevel% == 2 echo Access Denied - Could not stop service
if %errorlevel% == 0 echo Service stopped successfully
echo Errorlevel: %errorlevel%

Cambiar stopa starty funciona a la inversa.

Clinton
fuente
3

El reinicio manual del servicio está bien: services.msc tiene el botón "Reiniciar", pero en la línea de comando los comandos sc y net carecen de un interruptor "reiniciar" y si el reinicio está programado en el archivo cmd / bat, el servicio se detiene y se inicia de inmediato, a veces recibe un error porque el servicio aún no se ha detenido, necesita algo de tiempo para apagar las cosas.

Esto puede generar un error: sc stop sc start

Es una buena idea insertar tiempo de espera, utilizo ping (suena cada 1 segundo): sc stop ping localhost -n 60 sc start

Kuleris
fuente
2

Aquí está el comando de Windows 10 para iniciar Restaurar sistema usando lote:

sc config swprv start= Auto

También te pueden gustar esos comandos:

  • Cambiar el valor del registro para iniciar automáticamente la restauración del sistema

    REG AÑADIR "HKLM \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ SystemRestore" / v DisableSR / t REG_DWORD / d 0 / f

  • Crear un punto de restauración del sistema

    Wmic.exe / Namespace: \ root \ default Ruta SystemRestore Llame a CreateRestorePoint "djibe salvó su PC", 100, 12

  • Cambiar el uso del disco de Restaurar sistema

    vssadmin cambiar el tamaño del almacenamiento de sombras / for = C: / on = C: / maxsize = 10%

Disfrutar

djibe
fuente
1

SC puede hacer todo con los servicios ... iniciar, detener, verificar, configurar y más ...

Axeman
fuente
1

A veces puedes encontrar que la parada no funciona.

Mi SQlServer a veces hace esto. Usar la siguiente línea de comando lo mata. Si realmente necesitas tu script para matar cosas que no se detienen. Me gustaría que hiciera esto como último recurso

taskkill /pid [pid number] /f
Andrew Paté
fuente
0

Estoy escribiendo un servicio de Windows en C #, el ciclo de detención / desinstalación / compilación / instalación / inicio se cansó demasiado. Escribí un mini script, lo llamé reploy.baty lo coloqué en mi directorio de salida de Visual Studio (uno que tiene el ejecutable del servicio integrado) para automatizar el bucle.

Solo configura estos 3 vars

servicename : esto aparece en el panel de control del Servicio de Windows (services.msc)

slndir : carpeta (no la ruta completa) que contiene su archivo de solución (.sln)

binpath : ruta completa (no la ruta de la carpeta) al servicio ejecutable desde la compilación

NOTA: Esto debe ejecutarse desde la línea de comandos del desarrollador de Visual Studio para que el msbuildcomando funcione.

SET servicename="My Amazing Service"
SET slndir="C:dir\that\contains\sln\file"
SET binpath="C:path\to\service.exe"
SET currdir=%cd%

call net stop %servicename%
call sc delete %servicename%
cd %slndir%
call msbuild 
cd %bindir%
call sc create %servicename% binpath=%binpath%
call net start %servicename%
cd %currdir%

Tal vez esto ayude a alguien :)

sh87
fuente