1

Trying to asynchronously call a powershell script within an ASP.NET IHttHandler, I stumbled accross the example on http://msdn.microsoft.com/en-us/library/ee706580(v=vs.85).aspx. My own code looks like this:

using (PowerShell powershell = PowerShell.Create()) {
    powershell.AddScript("1..10 | foreach {$_ ; start-sleep -milli 500}");

    PSDataCollection<PSObject> output = new PSDataCollection<PSObject>();

    output.DataAdded += delegate(object sender, DataAddedEventArgs e) {
        PSDataCollection<PSObject> myp = (PSDataCollection<PSObject>)sender;
        Collection<PSObject> results = myp.ReadAll();
    };

    powershell.InvocationStateChanged += delegate(object sender, PSInvocationStateChangedEventArgs e) {
        if (e.InvocationStateInfo.State == PSInvocationState.Completed) {
            // Clean up
        }
    };

    IAsyncResult asyncResult = powershell.BeginInvoke<PSObject, PSObject>(null, output);
}

Unfortunately, the powershell script is obviously not being executed. No powershell process shows up in the task manager.

I set break points withing the DataAdded and IncovationStateChanged handlers. The first one never gets called, the second one shows, that e.InvocationStateInfo.State never becomes Completed but ends with Stopped.

What am I doing wrong?

2
  • This approach doesn't spin up a PowerShell process. You have the PowerShell engine running in-process. By using BeginInvoke, that same in-process engine executes your request async on another thread and not in another process. At some point, you should call EndInvoke(). Commented Mar 26, 2014 at 15:52
  • I guess you're refering to my remark, that no powershell process shows up? Still, the script isn't executed. InvocationStateInfo.State changes from running immediately to Stopping, although the script is expected to run 2:30 minutes. Commented Mar 26, 2014 at 16:11

1 Answer 1

1

This works in a console app:

using (PowerShell powershell = PowerShell.Create())
{
    powershell.AddScript("1..10 | foreach {$_ ; start-sleep -milli 500}");

    var output = new PSDataCollection<PSObject>();

    output.DataAdded += delegate(object sender, DataAddedEventArgs e)
    {
        Console.WriteLine(output[e.Index]);
        var myp = (PSDataCollection<PSObject>)sender;
        Collection<PSObject> results = myp.ReadAll();
    };

    powershell.InvocationStateChanged += delegate(object sender, PSInvocationStateChangedEventArgs e)
    {
        if (e.InvocationStateInfo.State == PSInvocationState.Completed)
        {
            // Clean up
        }
    };

    IAsyncResult asyncResult = powershell.BeginInvoke<PSObject, PSObject>(null, output);

    asyncResult.AsyncWaitHandle.WaitOne();
}

If you don't somehow synchronize or comeback later and wait for the invoke to finish, the PowerShell engine shuts down because powershell.Dispose() gets called as it falls out of your using {} scope.

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.