Поиск по сайту:

Как использовать команду Write Output в PowerShell


Команда Write-Output в PowerShell используется для отправки объекта или переменной в конвейер PowerShell. Когда она является последней командой в конвейере, вывод отображается в консоли.

Write-Output по сути является эквивалентом echo или print в других языках программирования.

В этой статье мы рассмотрим, как использовать командлет Write-Output и в чем разница между командлетом Write-Host и оператором Return.

Команда Write-Output PowerShell

Команда write-output отправит объект, строку или значение переменной в поток успешных сообщений PowerShell. Когда команда является последней в конвейере, результаты будут отображены в консоли.

Вы можете рассматривать командлет Write-Output как эквивалент команд Echo или Print в других языках программирования. Команда Echo даже является псевдонимом в PowerShell для командлета Write-Output.

Часто вам не нужно использовать командлет Write-Output, потому что поведение большинства командлетов по умолчанию заключается в том, чтобы отображать вывод, если за ними ничего не передается. Например, чтобы просмотреть все запущенные процессы на вашем компьютере, вы можете использовать командлет Get-Process:

Both command will return the same result:
Get-Process 
Get-Process | Write-Output

Или, когда вы хотите увидеть значение переменной, вы можете использовать Write-Output после нее, но это не обязательно:

$var = "Hello world"

These will all produce the same result in console
$var
$var | Write-Host
Write-Host $var
$var | Write-Output

Write-Output против Write-Host

Когда мы говорим о команде Write-Output, часто возникает вопрос, в чем разница с Write-Host и когда использовать что? Хотя обе команды часто отображают результат в консоли, между ними есть важная разница.

С помощью команды Write-Host вы выводите строку непосредственно в консоль. Однако с Write-Output вы отправляете строку в поток успешного завершения (stdout) PowerShell. И это различие действительно важно для понимания.

Посмотрите на пример ниже: функция получает пользователей из CSV-файла и, если пользователи существуют в Azure AD, добавляет пользователя в определённую группу. Теперь, чтобы отслеживать, что происходит, мы использовали командлет Write-Host:

Function Add-UsersToGroup {
  # Import the CSV File
  $users = (Import-Csv -Path $path -Delimiter $delimiter -header "name").name

  # Find the users in the Active Directory
  $users | ForEach-Object {
      $user = Get-AzureADUser -filter "$filter eq '$_'" | Select-Object ObjectID 

      if ($user) {
          Add-AzureADGroupMember -ObjectId $group -RefObjectId $user
          Write-Host "$_ added to the group"
      }else {
          Write-Warning "$_ not found in Azure AD"
      }
  }
}

Это отлично работает, когда вы запускаете скрипт локально в консоли. Но что, если вы используете эту функцию в Azure Runbook или хотите записать результаты в файл журнала? Вывод Write-Host будет утерян, потому что он был записан в консоль.

Если бы мы использовали Write-Output в этом случае, то сообщение об успешном добавлении пользователей в группу было бы отправлено в поток успешных операций PowerShell. Это позволяет нам просматривать результаты в журнале Azure Runbook или перенаправлять результаты этого скрипта в файл журнала.

Итак, вкратце, вы должны использовать Write-Host для интерактивных скриптов, которые выполняются непосредственно в консоли. Но для скриптов, которые выполняются в фоновом режиме или в Azure Runbooks, вы действительно должны использовать Write-Output.

Возврат vs Write-Output

Кроме того, распространенный вопрос заключается в том, в чем разница между return и Write-Output в PowerShell? Главная разница между ними заключается в том, что оператор return завершает выполнение функции или блока скрипта. В то время как cmdlet Write-Output только возвращает значение, но не завершает выполнение функции.

Мы можем увидеть разницу между ними на следующих примерах:

function calculation {
  param ($value)

  Write-Output "Please wait. Working on calculation..."
  Write-Output $value += 42
}

calculation -value 8

Result
Please wait. Working on calculation...
8
+=
42

В приведенном выше примере мы использовали только Write-Output командлет. Как вы можете видеть в результатах, расчет не выполняется, вместо этого каждый объект возвращается по отдельности.

function calculation {
  param ($value)

  return "Please wait. Working on calculation..."
  return $value += 42
}

calculation -value 8

Result
Please wait. Working on calculation...

Если бы мы использовали оператор return вместо этого, то вернется только строка, потому что оператор return завершит выполнение функции.

Таким образом, чтобы показать сообщение и вернуть расчет, нам нужно будет использовать оба:

function calculation {
  param ($value)

  Write-Output "Please wait. Working on calculation..."
  return $value += 42
}

calculation -value 8

Result
Please wait. Working on calculation...
50

Использование переменной внутри вывода

Хорошо знать, что мы можем использовать переменные внутри вывода команды write-output. Простая строковая переменная может быть включена в строку команды write-output при использовании двойных кавычек " ". Имейте в виду, что вы не можете использовать переменные внутри строк, заключенных в одинарные кавычки '. Разница здесь в том, что PowerShell обрабатывает только строки, заключенные в двойные кавычки.

$user = "megan@a-d.site"
Write-Output "Getting mailbox of $user"

Result
Getting mailbox of megan@a-d.site

Но когда вы работаете с объектами, вы могли заметить, что не можете вывести элементы объекта. Например, это не сработает:

$user = [PSCustomObject]@{
    DisplayName = "Megan"
    Email = "megan@a-d.site"
}

Write-Output "Getting mailbox of $user.displayname"

Result
Getting mailbox of @{DisplayName=Megan; Email=megan@a-d.site}.displayname

Чтобы показать отображаемое имя объекта пользователя, нам нужно обернуть его в скобки, как это:

$user = [PSCustomObject]@{
    DisplayName = "Megan"
    Email = "megan@a-d.site"
}

Write-Output "Getting mailbox of $($user.DisplayName)"

Result
Getting mailbox of Megan

Заключение

Имейте в виду, что поведение PowerShell по умолчанию заключается в отправке результатов команды в поток успеха, который затем отображается в консоли. Поэтому часто вам не нужно использовать команду Write-Output.

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

Надеюсь, вы нашли эту статью полезной. Если у вас есть вопросы, просто оставьте комментарий ниже.