Friday, August 20, 2010

Interacting with PowerShell from C#

Recently I had a client that wanted to be able to call PowerShell scripts from their Linux based Java application.  To facilitate, I created a web service that accepts a script name and a parameters collection and returns a customized response object.  There’s a helpful post on CodeProject with some sample code for calling PowerShell from C#.  It demonstrates how to instantiate a PowerShell pipeline and call cmdlets.  It even shows how to drop your application’s variables in the Pipeline, but it isn’t quite complete.  I also needed to setup command line arguments and see what changes the script made to my variable.

Basing my code on the CodeProject sample (thanks, jpmik) referenced above, I needed to add in some code to insert command line arguments.  That’s pretty easy as the PowerShell Command object has a Parameters collection.  You just have to instantiate the command object, configure it and drop it into the Pipeline.

Making an object variable available to the script was pretty easy, too.  The CodeProject example shows the use of the SetVariable method.  But if the PowerShell script changes the object, you have to follow up with a GetVariable call to pull the changed object out of the Pipeline.  Your object comes back wrapped up in a PSObject object, so you’ll have to dig it out.

Here’s what it looks like (this is a code fragment, some supporting elements are not included such as the definition of the MyResponse object):

Interacting with PowerShell from C#:
runspace = RunspaceFactory.CreateRunspace();
runspace.SessionStateProxy.SetVariable("MyResponse", response);
Pipeline pipeline = runspace.CreatePipeline();

Command cmd = new Command(scriptPath);

Collection<PSObject> results = pipeline.Invoke();

PSObject newResponse = (PSObject)runspace.SessionStateProxy.GetVariable("MyResponse");
response = (MyResponse)newResponse.BaseObject;


Thanks for reading.  Good luck.