2

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?

3 Answers 3

5

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
Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

1

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.

2 Comments

this answer answered my another question of why to use write-output if just writing a variable will do..
Thanks! Powershell is a bit daunting, especially if you're coming in from Bash; but its hooks into Windows can provide a ton of automation power.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.