function Invoke-WPFRunspace { <# .SYNOPSIS Creates and invokes a runspace using the given scriptblock and argumentlist .PARAMETER ScriptBlock The scriptblock to invoke in the runspace .PARAMETER ArgumentList A list of arguments to pass to the runspace .PARAMETER ParameterList A list of named parameters that should be provided. .EXAMPLE Invoke-WPFRunspace ` -ScriptBlock $sync.ScriptsInstallPrograms ` -ArgumentList "Installadvancedip,Installbitwarden" ` Invoke-WPFRunspace` -ScriptBlock $sync.ScriptsInstallPrograms ` -ParameterList @(("PackagesToInstall", @("Installadvancedip,Installbitwarden")),("ChocoPreference", $true)) #> [CmdletBinding()] [OutputType([System.IAsyncResult])] Param ( $ScriptBlock, $ArgumentList, $ParameterList ) if (-not ("WinUtilRunspaceCleanup" -as [type])) { Add-Type @" using System; using System.Management.Automation; public sealed class WinUtilRunspaceCleanupState { public PowerShell PowerShell { get; set; } public IAsyncResult Handle { get; set; } } public static class WinUtilRunspaceCleanup { public static readonly System.Threading.WaitOrTimerCallback Callback = Cleanup; public static void Cleanup(object state, bool timedOut) { var cleanupState = state as WinUtilRunspaceCleanupState; if (cleanupState == null || cleanupState.PowerShell == null || cleanupState.Handle == null) { return; } try { cleanupState.PowerShell.EndInvoke(cleanupState.Handle); } catch { } finally { cleanupState.PowerShell.Dispose(); } } } "@ } Initialize-WinUtilRunspacePool | Out-Null # Create a PowerShell instance $powershell = [powershell]::Create() # Add Scriptblock and Arguments to runspace [void]$powershell.AddScript($ScriptBlock) [void]$powershell.AddArgument($ArgumentList) foreach ($parameter in $ParameterList) { [void]$powershell.AddParameter($parameter[0], $parameter[1]) } $powershell.RunspacePool = $sync.runspace # Execute the RunspacePool $handle = $powershell.BeginInvoke() $cleanupState = [WinUtilRunspaceCleanupState]::new() $cleanupState.PowerShell = $powershell $cleanupState.Handle = $handle [System.Threading.ThreadPool]::RegisterWaitForSingleObject($handle.AsyncWaitHandle, [WinUtilRunspaceCleanup]::Callback, $cleanupState, -1, $true) | Out-Null # Return the handle return $handle }