В чем разница между echo и Write-Host в PowerShell?

Я запутался в разнице между echo и Write-Host в PowerShell. У меня два файла: POC.ps1 и validatePath.ps1. Эти файлы находятся на моей локальной машине, и я запускаю их на удаленной машине с помощью Invoke-Command. Я использую PowerShell v3.0.

Для выполнения обоих этих сценариев я использую команду:

.\POC.ps1 -filename C:\Users  -user Blaine

Вот два файла:

POC.ps1:

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

Вот где вещи становятся странными...

validatePath.ps1:

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"  <--- 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
}

Когда я запускаю выше script, это вывод:

C:\Users
This
Blaine
This is the file name: C:\Users Blaine
This is user:  <--- Notice where this line is?
This is the second part
This is the third part
C:\Users
Blaine
found!

Но если я изменю validatePath.ps1 на это:

Param([string] $filename,
      [string] $user)

function ValidatePath( $filename, $user, $fileType = "container" )
{
    Write-Host "This is the file name: $filename"
    echo "This is user: $user" <---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
}

Это вывод:

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: <---- Notice where this line is now?
C:\Users
Blaine
found!

Вы заметите, что строка "Это пользователь:" находится в разных местах. Почему это? Почему echo работает иначе, чем Write-Host?

UPDATE:

Что еще более странно, если я повторно запустил script два раза:

POC.ps1:

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

Это дает мне этот результат при использовании echo в validatePath.ps1:

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 <---- This line is here
C:\Users
found!
This is the file name: C:\saddfasdfj
This is user: Blaine <---- But now it here, where it should be? Wth?
Blaine, the path C:\saddfasdfj does not exist!

Ответ 1

echo является псевдонимом для Write-Output, который записывается в выходной поток Success. Это позволяет обрабатывать выходные данные через конвейеры или перенаправляться в файлы. Write-Host записывается непосредственно на консоль, поэтому выход не может быть перенаправлен/обработан далее.

Ответ 2

echo - это псевдоним для Write-Output. Если Write-Host напрямую пишет на "экран", запись-запись записывается в конвейер. Если конвейер не подается в какую-либо другую команду, он также заканчивается на "экране". Разница, которую вы видите, это Write-Host, которая записывается на экран непосредственно там, где Write-Output сначала проходит через конвейер и заканчивается на экране после Write-Host.

Использование Write-Output позволяет передавать/перенаправлять вывод в файл или в другую команду, где Write-Host не работает. Они должны использоваться в зависимости от того, что вы хотите.

Подробнее см. здесь.