2010-06-11 5 views
5

Ich möchte ein Zeitlimit für ein PowerShell (v2) -Skript festlegen, damit es nach Ablauf dieses Zeitlimits zwangsweise beendet wird.Wie können Sie ein Zeitlimit für das Ausführen eines PowerShell-Skripts festlegen?

Ich sehe in PHP haben sie Befehle wie set_time_limit und max_execution_time, wo Sie begrenzen können, wie lange das Skript und sogar eine Funktion ausführen kann.

Mit meinem Skript ist eine Do/While-Schleife, die auf die Zeit ist nicht geeignet, da ich eine externe Code-Bibliothek aufrufen, die für eine lange Zeit hängen kann.

Ich möchte einen Codeblock begrenzen und nur für x Sekunden ausführen, nach dem ich diesen Codeblock beenden und eine Antwort an den Benutzer zurückgeben, dass das Skript abgelaufen ist.

Ich habe Hintergrundjobs angeschaut, aber sie arbeiten in einem anderen Thread, also haben Sie keine Kill-Rechte über den Eltern-Thread.

Hat jemand damit zu tun oder eine Lösung?

Danke!

Antwort

1

Ich weiß, dass dies eine alte Post, aber ich verwendet habe das ist in meinen Skripten.

Ich bin mir nicht sicher, ob es der richtige Gebrauch davon ist, aber der System.Timers.Timer, den George aufstellte, gab mir eine Idee und es scheint für mich zu funktionieren.

Ich benutze es für Server, die manchmal auf einer WMI-Abfrage hängen, die Zeitüberschreitung verhindert, dass es stecken bleibt. Anstelle von write-host gebe ich die Nachricht dann in eine Protokolldatei aus, damit ich sehen kann, welche Server defekt sind, und sie bei Bedarf reparieren kann.

Ich benutze auch keine GUID Ich benutze den Server Hostname.

Ich hoffe, das macht Sinn und hilft Ihnen.

$MyScript = { 
       Get-WmiObject -ComputerName MyComputer -Class win32_operatingsystem 
      } 

$JobGUID = [system.Guid]::NewGuid() 

$elapsedEventHandler = { 
    param ([System.Object]$sender, [System.Timers.ElapsedEventArgs]$e) 

    ($sender -as [System.Timers.Timer]).Stop() 
    Unregister-Event -SourceIdentifier $JobGUID 
    Write-Host "Job $JobGUID removed by force as it exceeded timeout!" 
    Get-Job -Name $JobGUID | Remove-Job -Force 
} 

$timer = New-Object System.Timers.Timer -ArgumentList 3000 #just change the timeout here 
Register-ObjectEvent -InputObject $timer -EventName Elapsed -Action $elapsedEventHandler -SourceIdentifier $JobGUID 
$timer.Start() 

Start-Job -ScriptBlock $MyScript -Name $JobGUID 
1

Hier ist ein Beispiel für die Verwendung eines Timers. Ich habe es nicht persönlich versucht, aber ich denke, es sollte funktionieren:

function Main 
{ 
    # do main logic here 
} 

function Stop-Script 
{ 
    Write-Host "Called Stop-Script." 
    [System.Management.Automation.Runspaces.Runspace]::DefaultRunspace.CloseAsync() 
} 

$elapsedEventHandler = { 
    param ([System.Object]$sender, [System.Timers.ElapsedEventArgs]$e) 

    Write-Host "Event handler invoked." 
    ($sender -as [System.Timers.Timer]).Stop() 
    Unregister-Event -SourceIdentifier Timer.Elapsed 
    Stop-Script 
} 

$timer = New-Object System.Timers.Timer -ArgumentList 2000 # setup the timer to fire the elapsed event after 2 seconds 
Register-ObjectEvent -InputObject $timer -EventName Elapsed -SourceIdentifier Timer.Elapsed -Action $elapsedEventHandler 
$timer.Start() 

Main 
3

So etwas sollte auch funktionieren ...

$job = Start-Job -Name "Job1" -ScriptBlock {Do {"Something"} Until ($False)} 
Start-Sleep -s 10 
Stop-Job $job 
+0

Dies hat das Problem, dass es warten wird, bis die Zeit abgelaufen ist, auch wenn das Programm früher beendet wurde ... – Algoman