How would I return an object or multiple values from PowerShell to executing C# code

c#, powershell

Solution

In your powershell script you can build an Hashtable based on your necessity:

[hashtable]$Return = @{} 
$Return.ReturnCode = [int]1 
$Return.ReturnString = [string]"All Done!" 
Return $Return 

In C# code handle the Psobject in this way

 ReturnInfo ri = new ReturnInfo();
 foreach (PSObject p in psObjects)
 {
   Hashtable ht = p.ImmediateBaseObject as Hashtable;
   ri.ReturnCode = (int)ht["ReturnCode"];
   ri.ReturnText = (string)ht["ReturnString"];
 } 

//Do what you want with ri object.

If you want to use a PsCustomobject as in Keith Hill comment in powershell v2.0:

powershell script:

$return = new-object psobject -property @{ReturnCode=1;ReturnString="all done"}
$return

c# code:

ReturnInfo ri = new ReturnInfo();
foreach (PSObject p in psObjects)
   {
     ri.ReturnCode = (int)p.Properties["ReturnCode"].Value;
     ri.ReturnText = (string)p.Properties["ReturnString"].Value;
   }

Problem

Some C# code executes a powershell script with arguments. I want to get a returncode and a string back from Powershell to know, if everything was ok inside the Powershell script. What is the right way to do that - in both Powershell and C# Powershell ``` # Powershell script # --- Do stuff here --- # Return an int and a string - how? # In c# I would do something like this, if this was a method: # class ReturnInfo # { # public int ReturnCode; # public string ReturnText; # } # return new ReturnInfo(){ReturnCode =1, ReturnText = "whatever"}; ``` C# ``` void RunPowershellScript(string scriptFile, List<string> parameters) { RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration)) { runspace.Open(); RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace); Pipeline pipeline = runspace.CreatePipeline(); Command scriptCommand = new Command(scriptFile); Collection<CommandParameter> commandParameters = new Collection<CommandParameter>(); foreach (string scriptParameter in parameters) { CommandParameter commandParm = new CommandParameter(null, scriptParameter); commandParameters.Add(commandParm); scriptCommand.Parameters.Add(commandParm); } pipeline.Commands.Add(scriptCommand); Collection<PSObject> psObjects; psObjects = pipeline.Invoke(); //What to do here? //ReturnInfo returnInfo = pipeline.DoMagic(); } } class ReturnInfo { public int ReturnCode; public string ReturnText; } ``` I have managed to do this is some hacky ways by using Write-Output and relying on conventions like "last two psObjects are the values I am looking for", but it would break very easily.

Original source

Related problems