Mantener el espacio de ejecución de Powershell abierto en .Net

Estoy tratando de ejecutar un código de PowerShell desde VB.Net (¡los codificadores de C# también pueden ayudar si lo sabe!).
La primera parte del código, necesito conectarme a un controlador na con una contraseña y necesito mantener la conexión abierta. Tengo otros comandos que necesito ejecutar con un clic de un botón (obtener archivos, mostrar archivos, eliminar archivos específicos).
¿Cómo puedo mantener abierto el espacio de ejecución y ejecutar cada línea de código por separado? ¿Necesito usar "CreateRunspacePool"? Si es así, ¿cómo lo uso?

Edit: Estoy jugando ahora con RunspaceStateInfo.State, pero no conozco una forma de mantener abierta la conexión. Probé los eventos Page_Load y Page_Init para abrirlo solo una vez, pero en algún momento se cierra. Eliminé el comando ".Cerrar"

preguntado el 22 de mayo de 12 a las 13:05

1 Respuestas

No ha proporcionado mucha información, pero al hablar de Page_Load y Page_Init, supongo que está tratando de hacer esto desde una aplicación web ASP.NET. Presionando botones y configurando el estado en el Runspace.

Si se trata de una aplicación winforms, simplemente puede crear un espacio de ejecución:

Runspace runspace = RunspaceFactory.CreateRunspace(Host);

Y luego cree instancias de PowerShell y simplemente reutilice este espacio de ejecución:

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

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

Puede mantener el espacio de ejecución y simplemente ejecutar scripts entre clics de botón en ese mismo espacio de ejecución.

Sin embargo, si está en asp.net, esto es diferente, obviamente, cada vez que hace clic en un botón, se genera un nuevo hilo y no podrá mantener el espacio de ejecución en una variable, por lo que deberá hacer algo como mantenerlo en la sesión de la siguiente manera:

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"];
    }
}

Y luego probé que esto funciona:

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();
}

Cuando hago clic en el botón 1 y luego en el 3, aparece "Hola" y

Cuando hago clic en el botón 2 y luego en el 3, aparece "Mundo"

Así que reutilizó con éxito el espacio de ejecución.

contestado el 30 de mayo de 12 a las 21:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.