title: What is the difference between echo and Write-Host in PowerShell?
body: <p>I'm confused about the difference between <code>echo</code> and <code>Write-Host</code> in PowerShell. I have two files, <code>POC.ps1</code> &amp; <code>validatePath.ps1</code>. These files are on my local machine, and I'm running them on a remote machine using <code>Invoke-Command</code>. I am using PowerShell v3.0.</p>
  
  <p>To execute both of these scripts I use the command:</p>
  
  <pre><code>.\POC.ps1 -filename C:\Users  -user Blaine
  </code></pre>
  
  <p>Here are the two files:</p>
  
  <p>POC.ps1:</p>
  
  <pre><code>param($filename, $user)
  
  echo $filename
  echo "This"
  echo $user
  
  $responseObject = Invoke-Command testcomputer -FilePath .\validatePath.ps1  -ArgumentList($filename, $user) -AsJob
  
  while($responseObject.State -ne "Completed")
  {
  
  }
  
  $result = Receive-Job -Id $responseObject.Id -Keep
  echo $result
  </code></pre>
  
  <p>Here is where things get weird...</p>
  
  <p>validatePath.ps1:</p>
  
  <pre><code>Param([string] $filename,
        [string] $user)
  
  function ValidatePath( $filename, $user, $fileType = "container" )
  {
      Write-Host "This is the file name: $filename"
      Write-Host "This is user: $user"  &lt;--- Notice I'm using Write-Host here
      $fileExist = $null
      if( -not (test-path $filename -PathType $fileType) )
      {
          throw "$user, the path $filename does not exist!"
  
      }
      else
      {
           Write-Host "This is the second part"
           echo $filename found!
      }
      Write-Host "This is the third part"
      return $fileExist
  }
  
  
  try
  {
  
      ValidatePath($filename, $user)
  }
  catch
  {
      $e = $_.Exception
      echo $e
  }
  </code></pre>
  
  <p>When I run the above script, this is the output:</p>
  
  <pre><code>C:\Users
  This
  Blaine
  This is the file name: C:\Users Blaine
  This is user:  &lt;--- Notice where this line is?
  This is the second part
  This is the third part
  C:\Users
  Blaine
  found!
  </code></pre>
  
  <p>But if I change the <code>validatePath.ps1</code> to this:</p>
  
  <pre><code>Param([string] $filename,
        [string] $user)
  
  function ValidatePath( $filename, $user, $fileType = "container" )
  {
      Write-Host "This is the file name: $filename"
      echo "This is user: $user" &lt;---notice I'm using Echo here
      $fileExist = $null
      if( -not (test-path $filename -PathType $fileType) )
      {
          throw "$user, the path $filename does not exist!"
  
      }
      else
      {
           Write-Host "This is the second part"
           echo $filename found!
      }
       Write-Host "This is the third part"
      return $fileExist
  }
  
  
  try
  {
  
      ValidatePath($filename, $user)
  }
  catch
  {
      $e = $_.Exception
      echo $e
  }
  </code></pre>
  
  <p>This is the output:</p>
  
  <pre><code>C:\Users
  This
  Blaine
  This is the file name: C:\Users Blaine
  This is the second part
  This is the third part
  This is user: &lt;---- Notice where this line is now?
  C:\Users
  Blaine
  found!
  </code></pre>
  
  <p>You will notice that the line "This is the user:" is in different spots. Why is this? Why does <code>echo</code> work differently than <code>Write-Host</code>?</p>
  
  <p>UPDATE:</p>
  
  <p>What is even more strange is that if I rerun the script twice like this:</p>
  
  <p>POC.ps1:</p>
  
  <pre><code>param($filename, $user)
  
  echo $filename
  echo "This"
  echo $user
  
  $responseObject = Invoke-Command CAPTESTPK01 -FilePath .\validatePath.ps1  -ArgumentList $filename, $user -AsJob
  
  while($responseObject.State -ne "Completed")
  {
  
  }
  
  $result = Receive-Job -Id $responseObject.Id -Keep
  echo $result
  
  
  $filename = "C:\saddfasdfj"
  
  #Here I run the command again, using a different file name
  $responseObject = Invoke-Command CAPTESTPK01 -FilePath .\validatePath.ps1  -ArgumentList $filename, $user -AsJob
  
  while($responseObject.State -ne "Completed")
  {
     if($responseObject.State -eq "Failed")
     {
          echo "Failed"
          $result = Receive-Job -Id $responseObject.Id -Keep
          echo $result
          break
     }
  }
  
  $result = Receive-Job -Id $responseObject.Id -Keep
  echo $resul
  </code></pre>
  
  <p>It gives me this output when using <code>echo</code> in <code>validatePath.ps1</code>:</p>
  
  <pre><code>C:\Users
  This
  Blaine
  This is the file name: C:\Users
  This is the second part
  This is the third part
  This is user: Blaine &lt;---- This line is here
  C:\Users
  found!
  This is the file name: C:\saddfasdfj
  This is user: Blaine &lt;---- But now it's here, where it should be? Wth?
  Blaine, the path C:\saddfasdfj does not exist!
  </code></pre>