In Batch-Datei mit schtasks numerierte Tasks löschen, aber nicht alle Tasks
Hallo allerseits!
Bin noch ein Anfänger, möchte durch kleine Projekte lernen.
Ich möchte auf verschiedenen Netzwerk-Computern überprüfen, welche Tasks geplant sind und bestimmte davon löschen:
Es gibt auf den Rechnern drei Möglichkeiten:
1. es gibt keine geplanten Tasks
2. es gibt Tasks, die sollen bleiben
3. es gibt unterschiedlich viele Tasks, die mit einem konstanten Tasknamen und einer fortlaufenden Nummer bezeichnet werden (Test1, Test2, Test3...)
2. und 3. können auch gemeinsam vorkommen und das ist das eigentliche Problem.
mit query kann ich die Tasks anzeigen und in ein logfile ausgeben, dafür habe ich schon eine Batch-Datei.
wenn ich query durch delete ersetzen würde, müßte ich die entsprechenden Tasknamen angeben.
per Hand (über cmd) kann ich genau benannte Tasks oder alle löschen.
schtasks /Delete /S Computername /TN Test1
oder
schtasks /Delete /S Computername /TN *
Wie kann ich bei /TN eingeben, dass ich z.B. Test1-22 löschen möchte (soweit vorhanden) und dabei andere Tasks (z.B. Backup) bestehen lasse? Test* funktioniert nicht.
Ich habe mir schon soweit geholfen, dass ich für jeden Task eine extra Zeile geschrieben habe, und dabei die entsprechenden Fehlermeldungen, wenn die Tasks nicht da waren, mehr oder weniger ignoriert habe. Dabei habe ich auch jeden PC einzeln angesprochen und jedesmal, wenn die Datei abgearbeitet war, mit "ersetzen" den PC-Namen geändert und die Datei wieder angestoßen.
Das ist aber aufwendig und nicht sehr elegant. Da müßte es doch noch eine hübschere Methode geben, mit einer For-Schleife irgendwie vielleicht, dass ich eine Sprungmarke ansteuere, wenn es keine entsprechenden Tasks mehr gibt und der nächste PC aus der Liste dran ist?
Schon mal vielen Dank,
mwieapfel
Bin noch ein Anfänger, möchte durch kleine Projekte lernen.
Ich möchte auf verschiedenen Netzwerk-Computern überprüfen, welche Tasks geplant sind und bestimmte davon löschen:
Es gibt auf den Rechnern drei Möglichkeiten:
1. es gibt keine geplanten Tasks
2. es gibt Tasks, die sollen bleiben
3. es gibt unterschiedlich viele Tasks, die mit einem konstanten Tasknamen und einer fortlaufenden Nummer bezeichnet werden (Test1, Test2, Test3...)
2. und 3. können auch gemeinsam vorkommen und das ist das eigentliche Problem.
mit query kann ich die Tasks anzeigen und in ein logfile ausgeben, dafür habe ich schon eine Batch-Datei.
wenn ich query durch delete ersetzen würde, müßte ich die entsprechenden Tasknamen angeben.
per Hand (über cmd) kann ich genau benannte Tasks oder alle löschen.
schtasks /Delete /S Computername /TN Test1
oder
schtasks /Delete /S Computername /TN *
Wie kann ich bei /TN eingeben, dass ich z.B. Test1-22 löschen möchte (soweit vorhanden) und dabei andere Tasks (z.B. Backup) bestehen lasse? Test* funktioniert nicht.
Ich habe mir schon soweit geholfen, dass ich für jeden Task eine extra Zeile geschrieben habe, und dabei die entsprechenden Fehlermeldungen, wenn die Tasks nicht da waren, mehr oder weniger ignoriert habe. Dabei habe ich auch jeden PC einzeln angesprochen und jedesmal, wenn die Datei abgearbeitet war, mit "ersetzen" den PC-Namen geändert und die Datei wieder angestoßen.
Das ist aber aufwendig und nicht sehr elegant. Da müßte es doch noch eine hübschere Methode geben, mit einer For-Schleife irgendwie vielleicht, dass ich eine Sprungmarke ansteuere, wenn es keine entsprechenden Tasks mehr gibt und der nächste PC aus der Liste dran ist?
Schon mal vielen Dank,
mwieapfel
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 197065
Url: https://administrator.de/forum/in-batch-datei-mit-schtasks-numerierte-tasks-loeschen-aber-nicht-alle-tasks-197065.html
Ausgedruckt am: 15.04.2025 um 14:04 Uhr
13 Kommentare
Neuester Kommentar
wie wärs damit ...
was du noch machen kannst wäre die PC-Namen in eine Textdatei packen und mit einer FOR-Schleife durchlaufen. Lohnt aber nur wenn es extrem viele sind...
Grüße Uwe
@echo off
setlocal ENABLEDELAYEDEXPANSION
call :DELTASKS PC1
call :DELTASKS PC2
call :DELTASKS PC3
goto END
:DELTASKS
set computername=%1
for /L %%i IN (1,1,22) DO (
schtasks /Delete /S !Computername! /TN Test%%i
if !ERRORLEVEL! GTR 0 goto endloop
)
:endloop
:END
exit
was du noch machen kannst wäre die PC-Namen in eine Textdatei packen und mit einer FOR-Schleife durchlaufen. Lohnt aber nur wenn es extrem viele sind...
for /F %%i IN (rechner.txt) DO @(call :DELTASKS %%i)
Batches sind wunderbar für überschaubare Tasks. Bei derartigen Abfragen wären sie mir zu unsicher.
Die PowerShell bietet einen komplett anderen Ansatz. Hier wird mit Objekten gearbeitet statt mit Strings. Allerdings ist die Lernkurve hoch, und wie es aussieht, brauchst du WMI, was nicht einfach ist: http://powershell.com/cs/media/p/2611.aspx. Bei deiner schon komplexeren Aufgabe sind Batches aber m.E. keine Option.
Die PowerShell bietet einen komplett anderen Ansatz. Hier wird mit Objekten gearbeitet statt mit Strings. Allerdings ist die Lernkurve hoch, und wie es aussieht, brauchst du WMI, was nicht einfach ist: http://powershell.com/cs/media/p/2611.aspx. Bei deiner schon komplexeren Aufgabe sind Batches aber m.E. keine Option.
Hallo Renate,
also Codezeilen kannst du hier posten indem du sie mit code Tags umschließt. Wenn du einen Beitrag schreibst gibt es darüber einen Tab "Formatierungshilfe" dort kannst du das nachlesen.
Das obige Programm mit eingebauter For-Schleife für die Rechnernamen sieht so aus :
also Codezeilen kannst du hier posten indem du sie mit code Tags umschließt. Wenn du einen Beitrag schreibst gibt es darüber einen Tab "Formatierungshilfe" dort kannst du das nachlesen.
Das obige Programm mit eingebauter For-Schleife für die Rechnernamen sieht so aus :
@echo off
setlocal ENABLEDELAYEDEXPANSION
for /F %%i IN (rechner.txt) DO @(call :DELTASKS %%i)
goto END
:DELTASKS
set computername=%1
for /L %%i IN (1,1,22) DO (
schtasks /Delete /S !Computername! /TN Test%%i
if !ERRORLEVEL! GTR 0 goto endloop
)
:endloop
:END
exit
Das Problem bei obigen Code ist noch das wenn ein Task z.B. zwischen task1-22 fehlt bricht er die ganze Schleife ab; d.h. wenn ein Task fehlt aber dahinter noch weitere existieren werden diese nicht gelöscht. Deswegen musst du alle 22 Schritte durchlaufen um wirklich alle existierenden Tasks zu erfassen.
Mach den folgenden Abschnitt so:
Mach den folgenden Abschnitt so:
:DELTASKS
set computername=%1
for /L %%i IN (1,1,22) DO @(
schtasks /Delete /F /S !Computername! /TN test%%i >>nul 2>&1
if !ERRORLEVEL! == 0 (
echo Task 'test%%i' wurde auf !computername! entfernt >>!task_delete_log!
) else (
echo Task 'test%%i' existiert auf !computername! nicht >>!task_delete_log!
)
)
goto :eof
Du hast das goto :eof nach der DELTASKS-FOR-Schleife nicht mit eingefügt. Du musst dir die Markierung :DELTASKS wie eine Subroutine vorstellen die dann bei goto :eof wieder an die Stelle zurückspringt wo diese Subroutine aufgerufen wurde (hier war das die Stelle in der ersten Schleife: call :DELTASKS %%i). Diese Subroutine haben wir zusätzlich mit einem Parameter aufgerufen %%i, auf den du dann in der Subroutine mit %1 zugreifst.
Hoffe das war verständlich
; wenn nicht hier ein Link dazu.
Hier der komplette Code
Jetzt viel Spaß
Grüße Uwe
Hoffe das war verständlich
Hier der komplette Code
@echo off
::Variable Datum erstellen
set datname=%date:~8,2%%date:~3,2%%date:~0,2%
::erstelle Logdatei
set task_delete_log=D:\BatchDateien\task_delete%datname%.log
::schreibe Startzeit in Logdatei
echo START TaskDelete.BAT: %date% %time:~0,5% 1>>%task_delete_log% 2>&1
::schreibe Leerzeile in Logdatei
echo. 1>>%task_delete_log% 2>&1
setlocal ENABLEDELAYEDEXPANSION
for /F %%i IN (rechner.txt) do @(call :DELTASKS %%i)
goto end
:DELTASKS
set computername=%1
for /L %%i IN (1,1,22) DO @(
schtasks /Delete /F /S !Computername! /TN test%%i >>nul 2>&1
if !ERRORLEVEL! == 0 (
echo !computername! Task 'test%%i' wurde entfernt >>!task_delete_log!
) else (
echo !computername! keine weiteren Test-Tasks >>!task_delete_log!
goto :endloop
)
)
:endloop
goto :eof
::schreibe Leerzeile in Logdatei
echo. 1>>%task_delete_log% 2>&1
goto end
:end
echo ENDE TaskDelete.BAT: %date% %time:~0,5% 1>>%task_delete_log% 2>&1
Jetzt viel Spaß
Grüße Uwe
Für einen Test ob der jeweilige PC online ist sollte dieser Pings akzeptieren.
Dann baust du noch folgendes in dein Script zwischen Zeile 20 und 21 ein:
Gehe jetzt davon aus das die Rechner alle in einem lokalen Netz stehen, wenn nicht musst du eventuell die Wartezeit der Pings erhöhen (-w 500).
Dann baust du noch folgendes in dein Script zwischen Zeile 20 und 21 ein:
ping -n 1 -w 500 %computername% | find /c "TTL=" >nul
if %ERRORLEVEL% == 1 (
echo PC '%computername%' ist offline ! >>%task_delete_log
goto :endloop
)