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



Answers

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! :)

Question

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.




Related