Vindhya G
Vindhya G

Reputation: 1369

Different output by Write-Host and Write-Output to console by PowerShell

Below is a small PowerShell script.

function test() {
    $paramstring = "name=vindhya 
    id=182122"
    $hash_params = convertfrom-stringdata -stringdata $paramstring
    Write-Host $hash_params
    callee $hash_params
}


function callee() {
    param($hash_params)
    #$hash_params
}

test

Output is System.Collections.Hashtable.

But if Write-Host is replaced by Write-Output then,

function test() {
    $paramstring="name=vindhya 
    id=182122"
    $hash_params = convertfrom-stringdata -stringdata $paramstring
    Write-Output $hash_params
    callee $hash_params
}


function callee() {
    param($hash_params)
    #$hash_params
}

test

Output is

Name                           Value

----                           -----

name                           vindhya

id                             182122

Why are Write-Host and Write-Output behaving differently?

Upvotes: 2

Views: 3084

Answers (3)

poiu2000
poiu2000

Reputation: 980

Write-Output will pass the output to the next step of the pipeline. If you are at the end of the pipeline, then it will output to the console.

Write-Host will output to the console. If the output target is an object, it will call the toString() method to convert the object to a string and then output it. Usually the string is the type name of the object.

You can add another cmdlet, Out-String, in your code and then Write-Host would output similar content as Write-Output:

Write-Host ($hash_params | Out-String)

My test as below:

function test() {
    $paramstring = "name=vindhya
    id=18250"
    $hash_params = convertfrom-stringdata -stringdata $paramstring
    Write-Output $hash_params.toString()
    Write-Host ($hash_params | Out-String)
    callee $hash_params
}


function callee() {
    param($hash_params)
    #$hash_params
}

test

The output is:

System.Collections.Hashtable

Name        Value
----        ----
id          18250
name        vindhya

Upvotes: 5

Vish
Vish

Reputation: 2164

I've faced this with PowerShell. I believe writing objects is not usually well-accomplished using Write-Host - it appears better suited for strings. If you want to write objects, Write-Output is what you need to use.

From the Powershell documentation, Write-Output is used to "pipe objects through to the next command in the pipeline." Since there's no "next command", Write-Output is printing the object on the console.

Also, simply writing $objName appears to call Write-Output behind the scenes. Thus, if you wished to return your hashtable you'd do

function Foo {
    # Generate $hash_params
    $hash_params
    return
}

And this would pass $hash_params to whatever is calling Foo.

Upvotes: 1

Keith Hill
Keith Hill

Reputation: 201622

Write-Object sends objects thru PowerShell's formatting engine. This involves checking if there is a formatdata file with formatting instructions for the object's type. The formatting file can choose various different default display formats: table, list, wide, etc. If there is no formatting data for the object, PowerShell uses other criteria like number of public properties to determine whether to use table view or list view. As a last resort, it will try to coerce to a string usually using the object's ToString() method.

Write-Host does none of this (except the last part about coercing to a string). It just displays the strings you provide it. If you provide something that isn't a string, it attempts a simple coercion to string and that is it. Often this results in just the type name of the object.

Upvotes: 2

Related Questions