Ich möchte eine Batchdatei schreiben, die die folgenden Vorgänge ausführt:
Die Codebeispiele, die ich bisher gegoogelt habe, erwiesen sich als nicht funktionierend. Daher entschied ich mich, sie nicht zu posten.
Das Starten eines Dienstes erfolgt durch:
net start "SERVICENAME"
Verwenden Sie sc query <SERVICE_NAME>
, um den Status eines Dienstes zu überprüfen. Für if-Blöcke in Batchdateien gilt siehe Dokumentation .
Der folgende Code überprüft den Status des Dienstes MyServiceName
und startet ihn, falls er nicht läuft (der if-Block wird ausgeführt, wenn der Dienst nicht läuft):
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"
)
)
Erklärung, was es tut:
Für Ihre zweite Frage ist das Argument, das Sie an net start
übergeben möchten, der Dienstname, nicht der Anzeigename.
Um einen Dienst umzuschalten, gehen Sie wie folgt vor:
NET START "Verteilte Transaktion Koordinator" || NET STOP "Verteilt Transaktionskoordinator"
Mit dem folgenden Befehl können Sie feststellen, ob ein Dienst ausgeführt wird oder nicht:
sc query [ServiceName] | findstr /i "STATE"
Wenn ich es für mein NOD32 Antivirus ausführen, bekomme ich:
STATE : 4 RUNNING
Wenn es gestoppt wurde, würde ich bekommen:
STATE : 1 STOPPED
Sie können dies in einer Variablen verwenden, um festzustellen, ob Sie NET START verwenden oder nicht.
Der Dienstname sollte der Dienstname sein, nicht der Anzeigename.
Das sollte es tun:
FOR %%a IN (%Svcs%) DO (SC query %%a | FIND /i "RUNNING"
IF ERRORLEVEL 1 SC start %%a)
Sprachunabhängige Version.
@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
)
Ich habe gerade diesen Thread gefunden und wollte der Diskussion hinzufügen, wenn die Person keine Stapeldatei verwenden möchte, um Dienste neu zu starten. In Windows gibt es eine Option, wenn Sie zu Dienste, Diensteigenschaften und dann zur Wiederherstellung gehen. Hier können Sie Parameter für den Dienst einstellen. Möchte den Dienst neu starten, wenn der Dienst angehalten wird. Sie können auch einen zweiten Fehlerversuch ausführen, indem Sie den Computer neu starten.
Cuando se verwenden Sie Windows und Spanisch, el código debe quedar asi (bei Verwendung von Windows auf Spanisch ist der Code):
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 ist ein Service-Dienstprogramm, das die Anforderungen an einen Server erfüllt. Puedes ver el nombre del servicio viendo las propiedades del servicio. (Ersetzen Sie MYSERVICE durch den Namen des zu verarbeitenden Dienstes. Sie können den Namen des Dienstes in den Diensteigenschaften anzeigen.)
@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"
Ich wollte auch eine E-Mail erhalten, wenn der Dienst auf diese Weise gestartet wurde. Daher wurde @Ic-Code ein wenig hinzugefügt. Ich habe SendMail verwendet, aber es gibt andere Befehlszeilenoptionen Wie sendet man eine einfache E-Mail aus einer Windows-Batchdatei?
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.
)
)
)
)
Dienst mit Powershell-Skript starten. Sie können dies mit dem Taskplaner verknüpfen und ihn in Intervallen oder nach Bedarf auslösen. Erstellen Sie diese Datei als PS1-Datei, d. H. Mit der Erweiterung PS1, und lassen Sie diese Datei dann vom Taskplaner auslösen.
Starten Sie den Dienst
wenn Sie den Task-Scheduler auf dem Server verwenden, verwenden Sie dies in Argumenten
-noprofile -executionpolicy bypass -file "C:\Service Restart Scripts\StopService.PS1"
Überprüfen Sie, indem Sie dasselbe auf cmd ausführen. Wenn es funktioniert, sollte es auch für den Task-Scheduler funktionieren
$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
}
}
In Verbindung mit der Antwort von @DanielSerrano habe ich mich vor kurzem durch Lokalisierung des sc.exe
-Befehls, nämlich auf Spanisch, etwas gebissen. Mein Vorschlag ist es, die Linie und das Token, die den numerischen Dienststatus enthalten, genau zu bestimmen und zu interpretieren, was wesentlich robuster sein sollte:
@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
)
)
Getestet mit:
Für Windows Server 2012 unten ist das, was für mich funktioniert hat. Ersetzen Sie nur "SERVICENAME" durch den tatsächlichen Servicenamen:
@ECHO OFF
SET SvcName = SERVICENAME
SC QUERYEX "% SvcName%" | "STATE" FINDEN | FIND/v "RUNNING"> NUL && (ECHO% SvcName% wird nicht ausgeführt. ECHO START% SvcName%
NET START "%SvcName%" > NUL || (
ECHO "%SvcName%" wont start
EXIT /B 1
)
ECHO "%SvcName%" is started
EXIT /B 0
) || (ECHO "% SvcName%" führt EXIT/B 0 aus)
Vielleicht viel einfacher? Fügen Sie einfach die Liste der Antworten hier hinzu:
@for /f "tokens=1,* delims=: " %%a in ('sc queryex state=Inactive') do net start "%%b"
@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