0

I'm trying to run different PowerShell commands using .NET's System.Management library but I see that every time the runspaces share the same shell. To be more specific, if I open one PowerShell window on my OS and I run the following command:

Get-Runspace

I get the following output:

Id Name            ComputerName    Type          State         Availability
-- ----            ------------    ----          -----         ------------
 1 Runspace1       localhost       Local         Opened        Busy

If I now open another window and run the same command again I get the same output, from which I understand that I have different runspaces with the same name in different sessions. Correct me here if I'm wrong!

Now if I run the following code that runs the Get-Runspace command twice:

static void Main(string[] args)
{
    for (int i = 1; i <= 2; i++)
    {
        PowerShell ps = PowerShell.Create();
        ps.AddCommand("Get-Runspace");
        var result = ps.Invoke();

        foreach (PSObject elem in result)
        {
            Runspace runspace = (Runspace)elem.BaseObject;
            Console.WriteLine(runspace.Name);
        }
        Console.WriteLine();
    }
    Console.ReadLine();
}

I get the following output

Runspace1

Runspace1
Runspace2

which means that Runspace1 is visible from Runspace2 so they share the same shell.

I would instead expect the following output, in which the two runspaces are in separate shells:

Runspace1

Runspace1

Is this behaviour possible or my logic is broken? Note that closing the Runspace will not be enough to solve my problem.

1
  • If by "same shell" you mean "same process", then yeah, you got it :) What exactly is the problem you're trying to solve? Commented May 19, 2020 at 14:10

1 Answer 1

1

If by "same shell" you mean "the same process", then yes.

A Runspace is necessarily restricted to a single application domain, and application domains in .NET can't span multiple processes, so the relationship is:

+---------------------------------+
| Process                         |
| +-----------------------------+ |
| | AppDomain                   | |
| | +-----------+ +-----------+ | |
| | | Runspace1 | | Runspace2 | | |
| | +-----------+ +-----------+ | |
| +-----------------------------+ |
+---------------------------------+

Get-Runspace just enumerates the runspaces in the current host application domain.


You can isolate runspaces in a separate process if need be, use RunspaceFactory.CreateOutOfProcessRunspace():

using (PowerShell ps = PowerShell.Create())
{
    var isolatedShell = new PowerShellProcessInstance();
    var isolatedRunspace = RunspaceFactory.CreateOutOfProcessRunspace(TypeTable.LoadDefaultTypeFiles(), isolatedShell);

    ps.Runspace = isolatedRunspace;

    ps.AddCommand("Get-Runspace");
    var result = ps.Invoke();

    foreach (PSObject elem in result)
    {
        Runspace runspace = (Runspace)elem.BaseObject;
        Console.WriteLine(runspace.Name);
    }
    Console.WriteLine();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.