windowspowershellrunspace

Can a new PowerShell class instance be created in an already-running remote PowerShell process from Windows PowerShell?


There are some useful things that can be accomplished by connecting to an already-running PowerShell process. This answer, for example, uses that technique to gracefully stop the target PowerShell process by allowing the runspaces to first complete their cleanup. None of the obvious methods of stopping a process allow for such graceful shutdown.

That solution is implemented by way of creating a runspace and powershell class instance in the target process:

$pipe = [Runspaces.NamedPipeConnectionInfo]::new($Process.Id)
$rs = [runspacefactory]::CreateRunspace($pipe)
$rs.Open()
$ps = [powershell]::Create($rs)

That snippet relies on the PowerShell.Create(Runspace). That overload, however, is not available in the Windows PowerShell SDK.

I'm not very familiar with PowerShell remoting and runspaces and haven't spotted an obvious way to accomplish something similar using Windows PowerShell. Is it possible? If so, how?


Solution

  • The .Create(Runspace) overload was added in PowerShell 7 as you have already noticed but that isn't a problem for Windows PowerShell 5.1, there you just assign the created runspace to the .Runspace property:

    # try from PowerShell 5.1
    $proc = Start-Process pwsh -PassThru
    $pipe = [System.Management.Automation.Runspaces.NamedPipeConnectionInfo]::new($proc.Id)
    $rs = [runspacefactory]::CreateRunspace($pipe)
    $rs.Open()
    $ps = [powershell]::Create().AddScript('$PSVersionTable.PSVersion.ToString()')
    $ps.Runspace = $rs
    $ps.Invoke() # Should output the pwsh 7 version you have installed
    $proc.Kill()