2010-06-11 18 views
5

Quiero establecer un límite de tiempo en un script de PowerShell (v2) para que salga a la fuerza después de que el límite de tiempo haya expirado.¿Cómo se puede establecer un límite de tiempo para ejecutar un script de PowerShell?

Veo en PHP que tienen comandos como set_time_limit y max_execution_time donde puede limitar el tiempo de ejecución del script e incluso de una función.

Con mi secuencia de comandos, un ciclo do/while que está mirando en el momento no es apropiado, ya que estoy llamando a una biblioteca de código externo que puede colgarse durante mucho tiempo.

Quiero limitar un bloque de código y solo permitir que se ejecute durante x segundos, después de lo cual terminaré ese bloque de código y devolveré una respuesta al usuario de que el script agotó el tiempo de espera.

He visto trabajos en segundo plano, pero operan en un hilo diferente, por lo que no tendrán derechos de eliminación sobre el hilo principal.

¿Alguien ha tratado esto o tiene una solución?

Gracias!

Respuesta

1

Sé que esto es una entrada antigua, pero he utilizado esto en mis guiones

No estoy seguro de si es el uso correcto de él, pero el System.Timers.Timer que puso George me dio una idea y parece estar funcionando para mí.

Lo uso para servidores que a veces dependen de una consulta WMI, el tiempo de espera lo detiene. En lugar de write-host, publico el mensaje en un archivo de registro para poder ver qué servidores están rotos y solucionarlos si es necesario.

Tampoco utilizo un guid. Utilizo el nombre de host del servidor.

Espero que esto tenga sentido y lo ayude.

$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

Aquí hay un ejemplo del uso de un temporizador. Yo no lo he probado personalmente, pero creo que debería funcionar:

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

Algo como esto debería funcionar también ...

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

Esto tiene el problema de que esperará hasta que haya transcurrido el tiempo, incluso si el programa ha terminado antes ... – Algoman

Cuestiones relacionadas