As you may know, PowerShell has multiple streams. You can use those streams using following functions Write-Output, Write-Error, Write-Warning, Write-Verbose, Write-Debug, and Write-Information. It also has Write-Host which until PowerShell 5 was a bit special. Since PowerShell 5.1 it's a wrapper over Write-Information, so it doesn't kill puppies anymore and it's safe to use. While I could spend the next five pages trying to give my best and describe those streams, there are already many articles describing them in detail. Please check the following link if you need that information.
Before you read about Format-Stream you may also be interested in PSWriteColor which provides excellent options for working with colors using Write-Host. But let's not get too distracted. As you may even know there are nice commands that can help you output your HashTables, OrderedDictionary, PSCustomObjects, and many custom ones to a beautiful looking Table or a List. Those are Format-Table and Format-List.
The output from those commands is nice and really useful. But what if you want to use those commands in other streams? Such as Debug? Verbose? Or if you want to send that output to file?
PS C:\Users\pklys> Get-Process | Select-Object -First 5 |Format-List | Add-Content -Path 'C:\testor.txt' PS C:\Users\pklys> Get-Process | Select-Object -First 5 |Format-Table | Add-Content -Path 'C:\testor.txt'
You would get something like this
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
And in Debug/Verbose streams it's not available at all. Not useful right? So I've searched for a solution but couldn't find anything that would be enough for me to use. I always had some problems with them. And both Format-Table and Format-List have their benefits. That's where my Format-Stream function comes in that I've written over the weekend.
Format-Streams is supposed to fill the gap and allow you to work with Format-Table / Format-List in Verbose, Debug, Output, Informational and “Host” streams. It's also cross-platform working on Windows, Linux, and Mac. It's part of PSSharedGoods module even thou it could probably do on its own. But since I've recently fixed it's load time from, 12 seconds to 200 milliseconds, it's staying as part of PSSharedGoods module. Which isn't that bad since if you're using any of my other modules such as PSWriteWord, PSWriteExcel, PSAutomator, PSWinReporting you already have it. You just need to update it.
Get-Process | Select-Object -First 5 | Format-Stream Name, PriorityClass, HandleCount -Stream Debug -List Get-Process | Select-Object -First 5 | Format-Stream Name, PriorityClass, HandleCount -Stream Debug
As you can see above Format-Stream displays just fine in DEBUG stream in both Table and List modes. If you will give a wildcard or won't define properties at all Format-Stream will try to fill in the maximum size of the screen. You can also define additional parameters such as ExcludeProperty, AlightRight or HideTableHeaders.
Get-Process | Select-Object -First 5 | Format-Stream * -Stream Debug Get-Process | Select-Object -First 5 | Format-Stream -Stream Debug Get-Process | Select-Object -First 5 | Format-Stream -Stream Debug -ExcludeProperty Name, SI, Handles -AlignRight -HideTableHeaders
Like you've probably already noticed each output type behaves similar and works with same parameter sets. There are also Transpose and TransposeSort parameters which allows you to convert PSCustomObject to HashTable and vice versa.
Get-Process | Select-Object -First 5 | Format-Stream * -Stream Output Get-Process | Select-Object -First 5 | Format-Stream Name,ID -Stream Output -Transpose Get-Process | Select-Object -First 5 | Format-Stream Name,ID -Stream Output -List
There's one more trick to Output stream. You can output it to file. And it will keep its form.
Get-Process | Select-Object -First 5 | Format-Stream * -Stream Output | Add-Content -Path 'C:\test.txt' Get-Process | Select-Object -First 5 | Format-Stream Name,ID -Stream Output -Transpose | Add-Content -Path 'C:\test.txt' Get-Process | Select-Object -First 5 | Format-Stream Name,ID -Stream Output -List | Add-Content -Path 'C:\test.txt'
You can do an exactly the same thing with the Informational stream like with others if you need to. So I won't bother you with showing how and providing a screenshot. Finally, I wanted to show what Host is able to do. Apart from standard functionality that all other streams there's one little, maybe not very configurable feature.
Get-Process | Select-Object -First 5 | Format-Stream * -Stream Host -ForegroundColor Green,Red, Yellow -ForegroundColorRow 2,4,5 Get-Process | Select-Object -First 5 | Format-Stream Name,ID -Stream Host -ForegroundColor Green,Red, Yellow -ForegroundColorRow 2,4,5 Get-Process | Select-Object -First 5 | Format-Stream Name,ID -Stream Host -List
See what I did there? And it's cross-platform for all streams as well. Hope you like it. If there's already something similar on Google I wasn't able to found it. But it was fun to make it work. Enjoy.
Before you can use this script, you need to do a few manual steps. Since this script is published as a module, it's quite easy to set this up. Just execute the command below (accept warnings) .. and you can test it out.
Install-Module PSSharedGoods #Update-Module PSSharedGoods
You can of course install everything manually from GitHub (as everything is published there) but it will be far easier to just use Install-Module.
There also seems a way to do it without Write-Stream using some neat trick with Out-String. Choose your own poison.
Get-Process | Sort-Object WS -Descending | Select-Object -First 10 | Format-Table | Out-String | Write-Verbose Get-Process | Sort-Object WS -Descending | Select-Object -First 10 | Format-Table | Out-String | Write-Debug Get-Process | Sort-Object WS -Descending | Select-Object -First 10 | Format-Table | Out-String | Write-Output Get-Process | Sort-Object WS -Descending | Select-Object -First 10 | Format-Table | Out-String | Write-Host
Keep in mind that you won't see Debug or Verbose without explicitly asking for it.