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
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! :)
Wow, good question! I'll take a shot off the top of my head...
You could design a class in C# that represents the structure you want to use to pass data between the two. In the PS script, you could use an XmlWriter to craft an XML response and use Write-output
to spit out the XML string.
On the C# side, capture the standard out response, deserialize the XML into your new response class, and then process the result. Note that you can't write anything out to stdout other than your XML response, or else you won't be able to deserialze into the class.
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;
}