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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.