Skip to content

Instantly share code, notes, and snippets.

@pcgeek86
Last active April 1, 2024 18:24
Show Gist options
  • Save pcgeek86/fe8155b75497ac95a9891651ba70f5f1 to your computer and use it in GitHub Desktop.
Save pcgeek86/fe8155b75497ac95a9891651ba70f5f1 to your computer and use it in GitHub Desktop.
A PowerShell class that's intended to run jobs with timeouts.
class TimedScript {
# Set up some properties to hold individual job state
[System.Timers.Timer] $Timer = [System.Timers.Timer]::new()
[powershell] $PowerShell
[runspace] $Runspace = [runspacefactory]::CreateRunspace()
[System.IAsyncResult] $IAsyncResult
# Constructor: Create a new instance of TimedScript
# Parameter: ScriptBlock - the PowerShell ScriptBlock that will be executed.
# Parameter: Timeout - the timeout period of the ScriptBlock, in milliseconds
TimedScript([ScriptBlock] $ScriptBlock, [int] $Timeout) {
$this.PowerShell = [powershell]::Create()
$this.PowerShell.AddScript($ScriptBlock)
$this.PowerShell.Runspace = $this.Runspace
$this.Timer.Interval = $Timeout
# Set up an event handler for when the
Register-ObjectEvent -InputObject $this.Timer -EventName Elapsed -MessageData $this -Action ({
$Job = $event.MessageData
$Job.PowerShell.Stop()
$Job.Runspace.Close()
$Job.Timer.Enabled = $False
})
}
### Method: Call this when you want to start the job.
[void] Start() {
$this.Runspace.Open()
$this.Timer.Start()
$this.IAsyncResult = $this.PowerShell.BeginInvoke()
}
### Method: Once the job has finished, call this to get the results
[object[]] GetResult() {
return $this.PowerShell.EndInvoke($this.IAsyncResult)
}
}
$Job1 = [TimedScript]::new({ Start-Sleep -Seconds 2 }, 4000)
$Job2 = [TimedScript]::new({ Get-Process -Name s*; Start-Sleep -Seconds 2 }, 3000)
$Job3 = [TimedScript]::new({ Start-Sleep -Seconds 3 }, 1000)
$Job1.Start()
$Job2.Start()
$Job3.Start()
$Job1.PowerShell.HadErrors
$Job2.PowerShell.HadErrors
$Job3.PowerShell.HadErrors
Get-Runspace
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment