tl;dr:
Use:
$variable | Out-Host # or: Out-Host InputObject $variable
rather than
Write-Host $variable
to get meaningful output formatting.
Background information and debugging tips below.
Try a combination of the following approaches:
Use interactive debugging:
Use GUI editor Visual Studio Code with the PowerShell extension to place breakpoints in your code and inspect variable values interactively. (In Windows PowerShell you can also use the ISE, but it is obsolescent.)
Less conveniently, use the *-PSBreakpoint
cmdlets to manage breakpoints that are hit when you run your script in a console (terminal) window. A simple alternative is to add Wait-Debugger
statements to your script, which, when hit, break unconditionally.
Produce helpful debugging output:
Generally, use Write-Debug
rather than Write-Host
, which has two advantages:
You can leave Write-Debug
calls in your code for on-demand debugging at any time:
- They are silent by default, and only produce output on an opt-in basis, via (temporarily) setting
$DebugPreference = 'Continue'
beforehand or passing the -Debug
switch (if your script / function is an advanced one, though note that in Windows PowerShell this will present a prompt whenever a Write-Debug
call is hit).
- You do, however, pay a performance penalty for leaving
Write-Debug
calls in your code.
Debug output is clearly marked as such, colored and prefixed with DEBUG:
.
The problem you experienced with Write-Host
is that all Write-*
cmdlets perform simple .ToString()
stringification of their arguments, which often results in unhelpful representations, such as System.____comobject
in your case.
To get the same rich output formatting you would get in the console, use the following technique, which uses Out-String
as a helper command:
$variable | Out-String | Write-Debug
If you want to control the view (list vs. table vs. wide vs. custom) explicitly, insert a Format-*
call; e.g.:
$variable | Format-List | Out-String | Write-Debug
It is generally only the standard Out-*
cmdlets that use PowerShell's output formatting system.
A quick-and-dirty alternative to Write-Debug
is to use Out-Host
rather than Write-Host
- e.g., for quick insertion of debugging commands that you'll remove later; Out-Host
itself performs the usual output formatting, which simplifies matters:
# Default for-display formatting
$variable | Out-Host # or: Out-Host -InputObject $variable
# Explicit formatting
$variable | Format-List | Out-Host
Caveat: Aside from formatting, another important difference between Write-Host
and Out-Host
is that in PSv5+ only Write-Host
writes to the host via the information stream (stream number 6
), whereas Out-Host
truly writes directly to the host, which means that its output cannot be captured with redirections such as 6>
or *>
- see about_Redirection
.