Reputation: 105
I'm building a PowerShell host by C#, and I want to display the result after invoking PowerShell. Now I use the following method:
public static string GetLogQueriedString(
PSMemberInfoCollection<PSPropertyInfo> PSPropertyCollection)
{
string line = string.Empty;
foreach (var item in PSPropertyCollection)
{
if (!line.Equals(string.Empty)) line += ",";
line += item.Name + " : " + item.Value;
}
return line;
}
It works if the PSObject has many properties that I need, but in this situation, if the PSObject is a string, the result is not what I want. It will display "Length: 40", rather than the string itself.
And another question: if I execute several PowerShell commands, why will it display all the results, including the previous result. For example, I execute "ls; get-process", and it will display the result of "ls" and the result of "get-process".
Upvotes: 5
Views: 17133
Reputation: 1
More of your code is needed, but just a clarification of the previous answer.... It may be helpful to think of PSObject LIKE an array, in that each value is a key-value pair. Because of this, if you try to explicitly cast like ToString
, you'll get the object type, much like if you try to cast an array to a string you'll get a memory reference.
An easy solution is to use a foreach
. For your code:
foreach(var r in results) {
string toConsole = r.ToString()
}
Console.WriteLine(toConsole);
Upvotes: 0
Reputation: 201652
I think we need to see more of your code. The typical approach to display returned PSObjects is:
using (var ps = PowerShell.Create()) {
while (true) {
Console.WriteLine("Enter an expression:");
string input = Console.ReadLine();
if (String.IsNullOrWhiteSpace(input)) break;
ps.AddScript(input);
Collection<PSObject> results = ps.Invoke();
foreach (var result in results) {
Console.WriteLine(result);
}
}
}
If you don't need to access properties on the returned objects and all you're interested in is the formatted text try changing this line:
ps.AddScript(input + " | Out-String");
If you want to do custom formatting based on object type, you will need to test for the type and format as you see fit:
foreach (var result in results) {
var baseObj = result.BaseObject;
if (baseObj is System.Diagnostics.Process)
{
var p = (System.Diagnostics.Process) baseObj;
Console.WriteLine("Handles:{0}, NPM:{1}, PM:{2}, etc", p.HandleCount, p.NonpagedSystemMemorySize, p.PagedMemorySize);
}
else {
Console.WriteLine(result);
}
}
Upvotes: 5