2010-06-11 16 views
5

Je souhaite définir une limite de temps pour un script PowerShell (v2) afin qu'il s'exécute de force après l'expiration de cette limite de temps.Comment définir une limite de temps pour l'exécution d'un script PowerShell?

Je vois en PHP qu'ils ont des commandes comme set_time_limit et max_execution_time où vous pouvez limiter la durée d'exécution du script et même d'une fonction.

Avec mon script, une boucle do/while qui regarde l'heure n'est pas appropriée car j'appelle une bibliothèque de code externe qui peut simplement rester bloquée pendant longtemps. Je veux limiter un bloc de code et ne le laisser fonctionner que pendant x secondes, après quoi je vais terminer ce bloc de code et retourner une réponse à l'utilisateur que le script a expiré.

J'ai regardé des travaux d'arrière-plan, mais ils fonctionnent dans un thread différent, donc ils n'auront pas de droits d'arrêt sur le thread parent.

Est-ce que quelqu'un a traité ceci ou a une solution?

Merci!

Répondre

1

je sais que c'est un ancien poste, mais je l'ai utilisé ceci dans mes scripts.

Je ne suis pas sûr si c'est l'utilisation correcte de celui-ci, mais le System.Timers.Timer que George a mis en place m'a donné une idée et il semble fonctionner pour moi. Je l'utilise pour les serveurs qui se bloquent parfois sur une requête WMI, le timeout l'empêche de se bloquer. Au lieu de l'hôte d'écriture, je publie ensuite le message dans un fichier journal afin que je puisse voir quels serveurs sont cassés et les réparer si nécessaire.

Je n'utilise pas non plus un guid J'utilise le nom d'hôte du serveur. J'espère que cela a du sens et vous aide.

$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

Voici un exemple d'utilisation d'un temporisateur. Je ne l'ai pas essayé personnellement, mais je pense que cela devrait fonctionner:

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

Quelque chose comme cela devrait fonctionner aussi ...

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

Ceci a le problème qu'il attendra que le temps se soit écoulé, même si le programme s'est arrêté plus tôt ... – Algoman