1

I need to convert PowerShell PSObject to stream in a sameway the way PowerShell does. PowerShell also provides the output on standard stream in generic way.

e.g. $PSVersionTable only outputs 2 column ( Name, Value ) and not the whole Hashtable. So, I want each PSObject to process in a same standard way the way PowerShell does under the hood. Furthermore, I want to convert that to DataTable. I know, there are other links illustrating this problem, but they are operating on all properties of PSObject. Somehow, PowerShell doing this stuff out of the box.

Do I need to convert PSObject to other type?

Examples

PowerShell script outputs $PSVersionTable as

PSVersion      5.1.17134.228
PSEdition      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}

$host or Get-Host outputs as

Get-WebApplication outputs

Name             Application pool   Protocols    Physical Path                                                                                                                                                                                                                 
----             ----------------   ---------    -------------                                                                                                                                                                                                                 
IisHostedServer  DefaultAppPool     http        C:\TestDirectory\Src\IisHostedServer  

Get-ChildItem -Path "C:\TestDirectory\TestSubDir\Studio":

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       29.06.2018     11:54                TestFileDir
d-----       24.07.2018     16:37                TestSites
-a----       13.08.2018     11:53            343 TestXml.xml

Similarly there could be other reference or custom types.

I want to get these outputs in a same way in C# and need to show them either as String or DataTable. Is there any conversion available from PSObject to stream or something which returns above output in completely generic way?

while I am dealing with following method in C#:

var outputCollection = new PSDataCollection<PSObject>();

outputCollection.DataAdded += OnOutputDataAdded;
powerShell.Invoke(null, outputCollection);

private void OnOutputDataAdded(object sender, DataAddedEventArgs e)
{
    var records = (PSDataCollection<PSObject>) sender;
    var data = records[e.Index];
    var outputTable = ConverToLogableDataStream(data);
}
private void ConverToLogableDataStream(PSObject)
{
    ...
    ...
}
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Usman
  • 2,742
  • 4
  • 44
  • 82
  • There's a lot of magic happening in PowerShell output formatting. I covered some of it in [this answer](https://stackoverflow.com/a/40344479/1630171), but of course there's more to it than just that. For instance, what I outlined there doesn't explain why PowerShell by default displays the property `Mode` for file and directory objects, even though it's not among the properties defined in `.PSStandardMembers.DefaultDisplayPropertySet`. – Ansgar Wiechers Aug 29 '18 at 14:02
  • So, how to take powershell output stream using C# powershell api from PSObject. I only have PSObject in my hand and I want to convert it to stream so that user can see the output. Converting to DataTable is not manadatory. But how to extract from PSObject or convert PSObject to output stream – Usman Aug 29 '18 at 14:11
  • As mentioned, the default display properties are listed in `$obj.PSStandardMembers.DefaultDisplayPropertySet`, so you could start there. But as `Get-ChildItem` output shows, output may consist of more than just those. – Ansgar Wiechers Aug 29 '18 at 14:14
  • PSStanardMembers.DefaultDisplayPropertySet is not available in PSObject? Do you mean PSObject.Members? – Usman Aug 29 '18 at 14:16
  • Typo. I meant `$obj.PSStandardMembers.DefaultDisplayPropertySet`. `PSStandardMembers` is a hidden member like `PSObject` and `PSBase`. Use `$obj | Get-Member -Force` to see all (non-static) members of an object. – Ansgar Wiechers Aug 29 '18 at 14:19
  • How can I use $obj | Get-Member -Force in C# I want to execute in C# I have PSObject in C# code and need to use DefaultDisplayPropertySet – Usman Aug 29 '18 at 14:22
  • I'm not sure you can (I'm not a C# guy). I'm just trying to explain how formatting works in PowerShell. As far as my understanding goes, that is. – Ansgar Wiechers Aug 29 '18 at 14:27

1 Answers1

0

This question is quite old but have a look at ConvertTo-Json and work it into a data table or class of your choice from there (worked for me)

eg. Powershell: Get-Host | ConvertTo-Json

C#: JsonConvert.DeserializeObject< List < classname > > (PSObject)