简体   繁体   中英

Keeping Powershell runspace open in .Net

I'm trying to run some PowerShell code from within VB.Net (C# coders may also help if you know!).
The first part of the code, I need to connect to a na-controller with a password and I need to keep the connection open. I have other commands I need to run with a click of a button (get files, show files, delete specific ones).
How can I keep the runspace open and run each line of code separately? Do I need to use the "CreateRunspacePool"? If so, how do I use it?

Edit: I'm playing around now with the RunspaceStateInfo.State, but I don't know of a way to keep the connection open. I've tried the Page_Load and the Page_Init events to just have it open once, but somewhere along the line, it closes. I did remove the ".Close" command

You have not provided a lot of info but from you talking about the Page_Load and Page_Init I am assuming you are trying to do this from an ASP.NET web application. By pressing buttons and setting state on the Runspace.

If this is a winforms application you can simply create a runspace:

Runspace runspace = RunspaceFactory.CreateRunspace(Host);

And then create powershell instances and just reuse this runspace:

var ps1 = PowerShell.Create();
ps1.Runspace = runspace;
ps1.AddScript("Write-Host 'hello'")

var ps2 = PowerShell.Create();
ps2.Runspace = runspace;
ps2.AddScript("Write-Host 'world'")

You can keep the runspace around and simply run scripts between button clicks against that same runspace.

If you are in asp.net however this is different, obviously each time you click a button a new thread is spawned and you will not be able to keep the runspace in a variable, so you would need to do something like keep it around in the session as follows:

protected PSHost Host
{
    get
    {

        if (this.Session["Host"] == null)
        {
            var host = new MyHost();
            this.Session["Host"] = host;
        }

        return (PSHost)this.Session["Host"];
    }
}


protected Runspace Runspace
{
    get
    {

        if (this.Session["Runspace"] == null)
        {
            var rs = RunspaceFactory.CreateRunspace(Host);
            this.Session["Runspace"] = rs;
            rs.Open();
        }

        return (Runspace)this.Session["Runspace"];
    }
}

And then I tested that this works:

protected void Page_Load(object sender, EventArgs e)
{
    Button1.Click += new EventHandler(Button1_Click);
    Button2.Click += new EventHandler(Button2_Click);
    Button3.Click += new EventHandler(Button3_Click);
}

void Button3_Click(object sender, EventArgs e)
{
    var ps = PowerShell.Create();
    ps.Runspace = this.Runspace;
    ps.AddScript("$test | ft | out-string");
    var input = new List<object>();
    var output = new List<object>();
    ps.Invoke(input, output);
    TextBox1.Text = output.First().ToString();
}

void Button2_Click(object sender, EventArgs e)
{
    var ps = PowerShell.Create();
    ps.Runspace = this.Runspace;
    ps.AddScript("$test = 'world'");
    ps.Invoke();
}

void Button1_Click(object sender, EventArgs e)
{
    var ps = PowerShell.Create();
    ps.Runspace = this.Runspace;
    ps.AddScript("$test = 'hello'");
    ps.Invoke();
}

When I click button 1 and then 3 it displays "Hello" and

When I click button 2 and then 3 it displays "World"

So it sucesfully reused the runspace.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM