Better way to print object than Write-Host
Asked Answered
L

5

6

I use Write-Host analyze objects, but some times it is hard to understand what the object actually is.

Consider:

Write-Host $null
Write-Host @()
Write-Host @($null, $null)

Prints:

# Actually it prints nothing

I would like some thing like this:

Null
@()
@(Null, Null)

Any suggestions?

Latifundium answered 24/4, 2009 at 16:57 Comment(3)
So you want nothing to be something?Tale
Yes, "nothing to be something" :-) May be a way to dump object as YAML, etc.Latifundium
@{}|ConvertTo-Json -Compress will return {} as expected, but sadly not work for your cases.Brakpan
C
5

For this specific example, you can easily get what you want by sticking them in the property of an object. For the sake of an example, lets create an array with your three tests in it:

$tests = @($null,@(), @($null,$null))

function Write-Visible {
   param($InputObject) 

   New-Object PSObject -Property @{ Object=$InputObject } | 
       Out-String | Out-Host 
}

Of course, the Out-String | Out-Host stuff is just to make sure we don't actually output the objects to the pipeline, but behave like Write-Host does.

So now we can run our tests:

PS> Write-Visible $tests[0]

Object
------


PS> Write-Visible $tests[1]

Object
------
{}


PS> Write-Visible $tests[2]

Object
------
{$null, $null}

Of course, the problem with that is that it tends not to work so great for real objects because it's turning them into properties of an object, where they get rendered "ToString()" ... however, off the top of my head, I can't think how to invoke the rendering magic that happens there without the new object.

Chickenlivered answered 24/4, 2009 at 16:57 Comment(0)
D
2

You can write a function that does the pretty-printing for you. Something like the following might work for your needs:

function pp($a) {
    if ($a -eq $null) {
        return "Null"
    } elseif ($a -is [object[]]) {
        $b = @()
        foreach ($x in $a) {
            $b += (pp $x)
        }
        $s = "@(" + [string]::Join(",", $b) + ")"
        return $s
    } else {
        return $a
    }
}

This has, however still problems with an empty array on the shell (works fine from a .ps1 file, though). Also Hashtables aren't supported, but nested arrays are. Probably still needs some plumbing but might give a general direction.

The @($null, $null) array seems to be an ugly beast, resisting even comparing it to $null. Weird.

Demonstrable answered 24/4, 2009 at 17:30 Comment(3)
Couldn't you add something like if ($a.length -eq 0) {write-host "@()"}Picul
It worked already from my test script, that's what puzzles me. I tested @(), @(1,2), @(1,@(2,3)), $null and @($null,$null). Only the last one came out as "Null", the others worked like they should. But seemingly this is not the case when using the function directly from the commandline. But sure, go ahead and modify to your liking.Demonstrable
Sorry, I misread your answer and didn't try your code. Your code does works for me from the shell with an empty array.Picul
A
1

There are going to be multiple issues trying to do something like this.

  1. The "correct" or "powershell" way to change how write-host works is to use formatting files to define how you want the host you're using to display the objects in question. You can get more info from get-help about_format.ps1xml, or from the MSDN PowerShell Formatting File pages.
  2. You need to be specific to the "host" you are using. See get-help get-host for more info, or the TechNet page. There are AT LEAST three common hosts you want to be aware of:
    • the basic command-line, ConsoleHost
    • the basic PowerShell ISE, Windows PowerShell ISE Host
    • the Quest PowerGUI host, PowerGUIScriptEditorHost
  3. PowerShell handles the @() syntax in a special way, which can make dealing with empty arrays a difficult sometimes. According to this MSDN PowerShell Blog post:

    ... the

    @( … )

    operation is syntactic sugar for

    [array] $( … )

    So – if the statements in @() return a scalar, it will be wrapped in an array but if the result is already an array, then it won't be nested...

I'd love to be able to provide some code for this, but it's a bit beyond me at this point...

Aerodynamics answered 1/2, 2011 at 1:49 Comment(0)
C
1

Doesn't work well for the empty arrays, but you could use one of the format-xxx commands. This helps for formatting objects that don't have a helpful ToString override. E.g.

> $cmd = Get-Command -Name get-command
> $cmd

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Get-Command                                         Get-Command...

> write-host $cmd
Get-Command
> format-table -InputObject $cmd | out-string | out-host

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Get-Command                                         Get-Command... 
Corazoncorban answered 30/3, 2011 at 15:38 Comment(1)
You may also use format-list command instead of format-table.Hecklau
A
-1

You could try this:

Write-Host '$null'
Write-Host '@()'
Write-Host '@($null, $null)'
Albano answered 25/1, 2013 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.