Puzzle84
Puzzle84

Reputation: 540

echo in while loop get's added to my return value

I wasn't sure how to describe this problem in the title so here goes. I call a function from a script in another script. In that function i have a while loop that basically keeps looping through a set of ip's and looks up their hostname. when the while loop times out or we have all the host names. it returns the hostnames.

My problem is that the return value contains every single Write-Host i'm doing in that function.

i know it's because Write-Host puts stuff on the pipeline and the return just returns whatever it has.

How do i go about fixing this? The entire script i run get's logged in a log file which is why i want to have some verbose logging.

| out-null on write-host fixes the issue but it doesn't print the write-host values in the script.

in main.psm1 i have a function like so:

$nodes = @("ip1", "ip2", "ip3", "ip4")
$nodesnames = DoStuff -nodes $nodes

then in functions.psm1 i have functions like:

Function DoStuff
{
    param($nodes)
    $timeout = 300
    $timetaken = 0


    $sleepseconds = 5
    $nodenames = @("$env:COMPUTERNAME")

    while(($nodenames.count -lt $nodes.count) -and ($timetaken -lt $timeout))
    {
        try 
        {
            Write-Host "Stuff"
            foreach($node in $nodes)
            {
                $nodename = SuperawesomeFunction $node
                Write-Host "$nodename"
                if($nodenames -notcontains $nodename)
                {
                    $nodenames += @($nodename)
                }
            }
        }
        catch
        {
            Write-Host "DoStuff Failed because $_"
        }
        Start-Sleep $sleepseconds
        $timetaken += $sleepseconds
    }
    return $nodenames
}

Function SuperawesomeFunction 
{
    param($node)
    $nodename = [System.Net.Dns]::GetHostEntry("$node")
    return $nodename
}

Thanks.

Upvotes: 0

Views: 1557

Answers (1)

TheMadTechnician
TheMadTechnician

Reputation: 36332

So the answer is, your function is working like it is by design. In PowerShell a function will return output in general to the pipeline, unless specifically directed otherwise.

You used Echo before, which is an alias of Write-Output, and output is passed down the pipe as I mentioned before. As such it would be collected along with the returned $nodenames array.

Replacing Echo with Write-Host changes everything because Write-Host specifically tells PowerShell to send the information to the host application (usually the PowerShell Console or PowerShell ISE).

How do you avoid this? You could add a parameter specifying a path for a logfile, and have your function update the logfile directly, and only output the relevant data.

Or you can make an object with a pair of properties that gets passed back down the pipe which has the DNS results in one property, and the errors in another.

You could use Write-Error in the function, and set it up as an advanced function to support -errorvariable and capture the errors in a separate variable. To be honest, I'm not sure how to do that, I've never done it, but I'm 90% sure that it can be done.

Upvotes: 3

Related Questions