Wie in den Kommentaren von Lieven Keersmaekers angedeutet, hat der finally-Block keine Chance, zu laufen, wenn Sie die Task mit End beenden. Dies liegt daran, dass Ende den Prozess gerade beendet. PowerShell würde gerne den finally-Block ausführen, bevor er seine anderen aufregenden Dinge erledigt, aber PowerShell kann nach dem Prozessbeendigungssignal nichts mehr tun - es ist tot. Es gibt keinen Weg für einen Prozess, um damit umzugehen. In den Worten von Raymond Chen :
TerminateProcess ist die einfache Prozessabbruchfunktion. Es umgeht DLL_PROCESS_DETACH und alles andere im Prozess. Sobald Sie mit TerminateProcess beendet haben, wird in diesem Prozess kein Code mehr im Benutzermodus ausgeführt. Es ist weg. Pass nicht weiter. Sammle nicht 200 $.
Es gibt jedoch eine Problemumgehung. Da der Befehl "Task Scheduler" den Unterprozess des Taskprozesses nicht beendet, kann Ihr PowerShell-Hauptskript einen Watchdog-Prozess starten, um eine endgültige Bereinigung durchzuführen. Dieses Skript könnte ungefähr so aussehen (nennen wir es watchdog.ps1
):
$watched = Get-Process -Id $args[0] $watched.WaitForExit() 'Cleanup' >> c:\test.log
Es benötigt eine Prozess-ID, wartet, bis der Prozess beendet ist, und führt nur dann eine Bereinigung durch, das Äquivalent zu Ihrer endgültigen Blockierung.
Dann könnte Ihr Hauptskript so aussehen:
$myPid = [System.Diagnostics.Process]::GetCurrentProcess().Id $watchdog = Start-Process 'powershell' "-c .\watchdog.ps1 $myPid" -PassThru -WindowStyle Hidden 'Starting' sleep 10 'Finished'
Zu Beginn startet es das Watchdog-Skript und stellt seine eigene Prozess-ID bereit. Dann geht es normal weiter, sobald es fertig ist.
Wenn die Bereinigung des Watchdog nur dann erfolgen soll, wenn das Hauptskript unterbrochen wird, fügen Sie diese Zeile am Ende des Hauptskripts hinzu:
$watchdog.Kill()
Dadurch wird verhindert, dass der Watchdog über die zweite Zeile hinausgeht.
Ihre Umleitung gilt nur für den Hauptprozess. Der Watchdog muss also seine eigene Ausgaberichtung festlegen. Abhängig von der Konfiguration Ihrer geplanten Aufgabe müssen Sie möglicherweise den vollständigen Pfad zum watchdog-Skript im Befehl watchdog-launching des Hauptscripts angeben.