Trondh
Trondh

Reputation: 3351

PowerShell BeginInvoke - PSInvocationSettings not working

I have the following c# code for calling powershell using BeginInvoke. I have the following requirements: - Eventhandlers for "live" streaming of the output, verbose and error streams - I need to be able to inject an ErrorActionPreference when executing the script

My code looks as follows (powershellScriptSettings.StopOnErrors is always bool true):

powershellSettings.ErrorActionPreference = powershellScriptSettings.StopOnErrors ? ActionPreference.Stop : ActionPreference.Continue;

IAsyncResult async = powerShellInstance.BeginInvoke<PSObject, PSObject>(null, output, powershellSettings, null, null);

//wait for it to complete
try
{
    powerShellInstance.EndInvoke(async);
}

Looking at the output stream, I can see that this code executes both write-error commands and that the value of $ErrorActionPreference is at its default (Continue):

$ErrorActionPreference
Write-error 'err1'
Write-Error 'err2'

So it's fairly obvious that my powershellSettings are not having an effect. I know I can just add the string $ErrorActionPreference=Stop to the beginning of my input script, but I kinda want to do it the "C#" way and use the available functionality in the Powershell api.

I'm wondering if my code is faulty due to the fact that I haven't implemented BeginInvoke's callback function - I can't see that I need it as EndInvoke waits for the script to complete anyways.

Any pointers appreciated!

Upvotes: 2

Views: 1426

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174900

I took a look at the PowerShell class source code on GitHub.

If you search through the source code, you'll find that the ErrorActionPreference property is only being honored when running in "batch mode".

From looking at the code and tinkering around with the PowerShell.Commands property, it seems to me that this simply means that multiple statements have been added to the instance. This kinda makes sense - if there's only one statement to execute then there's no point to trying to figure out whether to continue or not.

You should therefore be able to trigger inspection of the ErrorActionPreference property by simply adding an empty statement before executing:

powerShellInstance.AddStatement();
IAsyncResult async = powerShellInstance.BeginInvoke<PSObject, PSObject>(null, output, powershellSettings, null, null);

Upvotes: 2

Related Questions