Shmoopy
Shmoopy

Reputation: 5534

Customize PowerShell object output

I have a C# Class:

class SomeObject
{
    int id;
    string displayName;
    // And so on..

   public override string ToString()
   {
       return "Hello";
   }
}

I have a command, Get-SomeObject that returns an instance of SomeObject. However, if I do:

$o = Get-SomeObject
$o

PowerShell prompts the values of SomeObject properties, meaning:

id = 5
displayName = Pikachu

Is there anyway to get PowerShell to call the ToString() method of that object, so "Hello" is printed to the console instead?

Upvotes: 0

Views: 1028

Answers (1)

Keith Hill
Keith Hill

Reputation: 201972

By default, PowerShell will display the property values for objects with no formatting information. For four or fewer properties, table format is used. For five or more properties, list format is used. If you want to control how your object is displayed, you should add formatting data via the Update-FormatData. See the man pages on Update-FormatData and about_Format.ps1xml.

Also, you should not write to the Console in ToString(). Your ToString() method should just return a string. BTW, you can also get PowerShell to call ToString() by casting the object to [string] e.g.:

PS C:\> Add-Type -TypeDefinition @'
>>> public class SomeObject
>>> {
>>>     public int Id {get; set;}
>>>     public string DisplayName {get; set;}
>>>     // And so on..
>>>
>>>    public override string ToString()
>>>    {
>>>        return "Hello";
>>>    }
>>> }
>>> '@

PS C:\> $o = New-Object SomeObject
PS C:\> [string]$o
Hello

If you want to follow the format data route, here is an example of how to do that:

PS C:\> @'
>>> <Configuration>
>>>   <ViewDefinitions>
>>>     <View>
>>>       <Name>SomeObject</Name>
>>>       <ViewSelectedBy>
>>>          <TypeName>SomeObject</TypeName>
>>>       </ViewSelectedBy>
>>>       <TableControl>
>>>         <TableHeaders>
>>>           <TableColumnHeader>
>>>             <Label>SomeObject</Label>
>>>           </TableColumnHeader>
>>>         </TableHeaders>
>>>         <TableRowEntries>
>>>           <TableRowEntry>
>>>             <TableColumnItems>
>>>               <TableColumnItem>
>>>                 <ScriptBlock>$_.ToString()</ScriptBlock>
>>>               </TableColumnItem>
>>>             </TableColumnItems>
>>>           </TableRowEntry>
>>>          </TableRowEntries>
>>>       </TableControl>
>>>     </View>
>>>   </ViewDefinitions>
>>> </Configuration>
>>> '@ > SomeObject.format.ps1xml

PS C:\> Update-FormatData .\SomeObject.format.ps1xml
PS C:\> $o

SomeObject
----------
Hello

If your SomeObject type is in a namespace be sure to update the <TypeName> element in the format data above to reflect the namespace qualified type name.

Upvotes: 3

Related Questions