How can you set a time limit for a PowerShell script to run for? How can you set a time limit for a PowerShell script to run for? powershell powershell

How can you set a time limit for a PowerShell script to run for?


Something like this should work too...

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


Here's my solution, inspired by this blog post. It will finish running when all has been executed, or time runs out (whichever happens first).

I place the stuff I want to execute during a limited time in a function:

function WhatIWannaDo($param1, $param2){    # Do something... that maybe takes some time?    Write-Output "Look at my nice params : $param1, $param2"}

I have another funtion that will keep tabs on a timer and if everything has finished executing:

function Limit-JobWithTime($Job, $TimeInSeconds, $RetryInterval=5){    try    {        $timer = [Diagnostics.Stopwatch]::StartNew()        while (($timer.Elapsed.TotalSeconds -lt $TimeInSeconds) -and ('Running' -eq $job.JobStateInfo.State)) {            $totalSecs = [math]::Round($timer.Elapsed.TotalSeconds,0)            $tsString = $("{0:hh}:{0:mm}:{0:ss}" -f [timespan]::fromseconds($totalSecs))            Write-Progress "Still waiting for action $($Job.Name) to complete after [$tsString] ..."            Start-Sleep -Seconds ([math]::Min($RetryInterval, [System.Int32]($TimeInSeconds-$totalSecs)))        }        $timer.Stop()        $totalSecs = [math]::Round($timer.Elapsed.TotalSeconds,0)        $tsString = $("{0:hh}:{0:mm}:{0:ss}" -f [timespan]::fromseconds($totalSecs))        if ($timer.Elapsed.TotalSeconds -gt $TimeInSeconds -and ('Running' -eq $job.JobStateInfo.State)) {            Stop-Job $job            Write-Verbose "Action $($Job.Name) did not complete before timeout period of $tsString."        } else {            if('Failed' -eq $job.JobStateInfo.State){                $err = $job.ChildJobs[0].Error                $reason = $job.ChildJobs[0].JobStateInfo.Reason.Message                Write-Error "Job $($Job.Name) failed after with the following Error and Reason: $err, $reason"            }            else{                Write-Verbose "Action $($Job.Name) completed before timeout period. job ran: $tsString."            }        }            }    catch    {    Write-Error $_.Exception.Message    }}

... and then finally I start my function WhatIWannaDo as a background job and pass it on to the Limit-JobWithTime (including example of how to get output from the Job):

#... maybe some stuff before?$job = Start-Job -Name PrettyName -Scriptblock ${function:WhatIWannaDo} -argumentlist @("1st param", "2nd param")Limit-JobWithTime $job -TimeInSeconds 60Write-Verbose "Output from $($Job.Name): "$output = (Receive-Job -Keep -Job $job)$output | %{Write-Verbose "> $_"}#... maybe some stuff after?


I know this is an old post, but I have used this in my scripts.

I am not sure if its the correct use of it, but the System.Timers.Timer that George put up gave me an idea and it seems to be working for me.

I use it for servers that sometimes hang on a WMI query, the timeout stops it getting stuck.Instead of write-host I then output the message to a log file so I can see which servers are broken and fix them if needed.

I also don't use a guid I use the servers hostname.

I hope this makes sense and helps you.

$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 hereRegister-ObjectEvent -InputObject $timer -EventName Elapsed -Action $elapsedEventHandler -SourceIdentifier $JobGUID$timer.Start()Start-Job -ScriptBlock $MyScript -Name $JobGUID