Whenever a function returns objects with more than four properties, PowerShell formats the output as list, else as table. Before you learn a new trick to influence this behavior, check for yourself. The function below returns an object with 6 properties:
function Get-TestData { # if a function is to return more than one information kind, # wrap it in a custom object [PSCustomObject]@{ # wrap anything you'd like to return ID = 1 Random = Get-Random Date = Get-Date Text = 'Hello' BIOS = Get-WmiObject -Class Win32_BIOS User = $env:username } }
The result turns into a list:
PS> Get-TestData ID : 1 Random : 147704985 Date : 25.05.2018 13:09:26 Text : Hello BIOS : \\DESKTOP-7AAMJLF\root\cimv2:Win32_BIOS.Name="1.6.1",SoftwareElementID="1.6.1",SoftwareElementState=3,TargetOperatingSys tem=0,Version="DELL - 1072009" User : tobwe
When you remove properties and limit them to 4 or less, PowerShell produces a table:
PS> Get-TestData ID Random Text User -- ------ ---- ---- 1 567248729 Hello tobwe
Typically, tabular design is easier to read, especially when there are multiple data sets. While you get tabular design by default with 4 or less properties, you might not always want to limit your return values to just 4 properties. So why not do it like cmdlets do?
Cmdlets by default show only a fraction of properties:
PS> Get-Service | Select-Object -First 1 Status Name DisplayName ------ ---- ----------- Running AdobeARMservice Adobe Acrobat Update Service
You get the full property list only when you use Select-Object and ask for all properties explicitly:
PS> Get-Service | Select-Object -First 1 -Property * Name : AdobeARMservice RequiredServices : {} CanPauseAndContinue : False CanShutdown : False CanStop : True DisplayName : Adobe Acrobat Update Service DependentServices : {} MachineName : . ServiceName : AdobeARMservice ServicesDependedOn : {} ServiceHandle : Status : Running ServiceType : Win32OwnProcess StartType : Automatic Site : Container
Apparently, there are first- and second-class citizens. In your own functions, you define the first-class citizen like so:
function Get-TestData { # define the first-class citizen [string[]]$visible = 'ID','Date','User' $info = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',$visible) [PSCustomObject]@{ # wrap anything you'd like to return ID = 1 Random = Get-Random Date = Get-Date Text = 'Hello' BIOS = Get-WmiObject -Class Win32_BIOS User = $env:username } | # add the first-class citizen info to your object Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $info -PassThru }
Now, your function behaves exactly like cmdlets, and as long as you don’t define more than 4 first-class citizens, you get tabular design by default:
PS> Get-TestData ID Date User -- ---- ---- 1 25.05.2018 13:15:15 tobwe PS> Get-TestData | Select-Object -Property * ID : 1 Random : 1298877814 Date : 25.05.2018 13:15:22 Text : Hello BIOS : \\DESKTOP-7AAMJLF\root\cimv2:Win32_BIOS.Name="1.6.1",SoftwareElementID="1.6.1",SoftwareElementState=3,TargetOperatingSys tem=0,Version="DELL - 1072009" User : tobwe