Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

powershell

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.

like image 547
Kjensen Avatar asked Apr 11 '12 12:04

Kjensen


People also ask

How do I return multiple values in PowerShell?

To return multiple values from a PowerShell function, you can return an array of objects. The following example returns the multiple values from a function num using an array. Code: function num() { $a = 4,5,6 return $a } $b=num Write-Host "The numbers are $($b[0]),$($b[1]),$($b[2])."

How do I return a value from a PowerShell script?

The return keyword exits a function, script, or script block. It can be used to exit a scope at a specific point, to return a value, or to indicate that the end of the scope has been reached.

How does a PowerShell function return a value?

If you are inside of a function and return a value with the return keyword, the function will return that value and exit the function. The return keyword causes the function to exit after outputting the first process. PowerShell will then generate output for both processes.


2 Answers

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;    } 
like image 106
CB. Avatar answered Sep 19 '22 12:09

CB.


CB.'s answer worked great for me with a minor change. I did not see this posted anywhere (in regards to C# and PowerShell) so I wanted to post it.

In my PowerShell script I created created a Hashtable, stored 2 values in it (a Boolean and an Int) and then converted that into a PSObject:

$Obj = @{}  if($RoundedResults -ilt $Threshold) {     $Obj.bool = $true     $Obj.value = $RoundedResults } else {     $Obj.bool = $false     $Obj.value = $RoundedResults }  $ResultObj = (New-Object PSObject -Property $Obj)  return $ResultObj 

And then in my C# code I did the same thing that CB. did but I had to use Convert.ToString in order to successfully get the values back:

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

I found the answer to this via the following StackOverflow post: https://stackoverflow.com/a/5577500

Where Kieren Johnstone says:

Use Convert.ToDouble(value) rather than (double)value. It takes an object and supports all of the types you asked for! :)

like image 24
hvaughan3 Avatar answered Sep 21 '22 12:09

hvaughan3