Private/New-psRunspace.ps1
<#
.SYNOPSIS Start scriptblock in background runspace, which will disposed when finished .DESCRIPTION Start scriptblock in background runspace, which will disposed when finished .PARAMETER SetVariable Variables to be parsed in runspace .PARAMETER ScriptBlock Scriptblock running in runspace .PARAMETER CallbackBlock Scriptblock triggert by events via Invoke-psRunspaceEvent .PARAMETER $CallbackName Name of sourceIdentifier for CallbackBlock parameter .PARAMETER DisposeBlock Scriptblock for custom actions on dispose .NOTES added in version 0.0.1 #> function New-psRunspace { [CmdletBinding()] param ( [Parameter(Mandatory,Position=1,ParameterSetName="Scriptblock")] [Parameter(Mandatory,Position=1,ParameterSetName="CallBack")] [scriptBlock]$ScriptBlock, [Parameter(Position=2,ParameterSetName="Scriptblock")] [Parameter(Position=2,ParameterSetName="CallBack")] [string[]]$SetVariable, [Parameter(Position=3,ParameterSetName="Scriptblock")] [Parameter(Position=3,ParameterSetName="CallBack")] [string]$Name, [Parameter(Mandatory,ParameterSetName="CallBack",Position=3)] [scriptBlock]$CallbackBlock, [Parameter(Mandatory,ParameterSetName="CallBack",Position=4)] [string]$CallbackName, [Parameter(Position=5,ParameterSetName="Scriptblock")] [Parameter(Position=5,ParameterSetName="CallBack")] [scriptBlock]$DisposeBlock ) # Create New Runspace ######################################### $rs = [runspacefactory]::CreateRunspace() $rs.ApartmentState = "STA" $rs.ThreadOptions = "ReuseThread" if ($Name) { $rs.Name = $Name } $rs.Open() | Out-Null foreach ($varName in $SetVariable) { $v = (Get-Variable -Name $varName).Value $rs.SessionStateProxy.SetVariable($varName, $v) } # Add Callback ######################################### if ($CallbackBlock) { Register-EngineEvent -SourceIdentifier $CallbackName -Action $CallbackBlock $SyncHost = [Hashtable]::Synchronized(@{}) $SyncHost.Host = $Host $rs.SessionStateProxy.SetVariable('SyncHost', $SyncHost) } $ps = [PowerShell]::Create().AddScript($ScriptBlock) $ps.Runspace = $rs $ps.BeginInvoke() | Out-Null # Create Powershell Instance ######################################### $ps = [PowerShell]::Create().AddScript($ScriptBlock) $ps.Runspace = $rs $ps.BeginInvoke() | Out-Null # Cleanup Eventhandler ######################################### $MessageData = @{} if ($DisposeBlock) { $MessageData.DisposeBlock = $DisposeBlock } if ($CallbackName) { $MessageData.CallbackName = $CallbackName } Register-ObjectEvent -InputObject $rs -EventName 'AvailabilityChanged' -Action { if ($Sender.RunspaceAvailability -eq "Available") { # Invoke Dispose Block ######################################### $sb = $event.MessageData.DisposeBlock if ($sb) { $sb.invoke() } # Cleanup callback ######################################### $CallbackName = $event.MessageData.CallbackName if ($CallbackName) { Get-EventSubscriber -SourceIdentifier $CallbackName | Unregister-Event } $Sender.Closeasync() $Sender.Dispose() } } -MessageData $MessageData | Out-Null return $rs } |