Командлет Tee-Object: мощный инструмент PowerShell для перенаправления вывода

Опубликовано: 15 Марта, 2023
Командлет Tee-Object: мощный инструмент PowerShell для перенаправления вывода

Как человек, который пишет множество сценариев PowerShell, я обнаружил, что довольно часто использую определенные командлеты и приемы написания сценариев. На прошлой неделе мне пришло в голову, что я никогда не писал об одном конкретном командлете PowerShell, который может немного упростить написание сложных сценариев. Я говорю о командлете Tee-Object.

Прежде чем я расскажу вам, что делает командлет Tee-Object, мне нужно уделить немного времени и рассказать о «обычном» способе работы PowerShell. Как правило, когда вы используете командлет Get (Get-VM, Get-Service, Get-Process и т. д.), вы в конечном итоге делаете одно из двух. Один из вариантов — отправить выходные данные по конвейеру, а затем либо отобразить их на экране, либо записать в файл. Другой вариант — записать выходные данные командлета в переменную. Но что, если вам нужно сделать и то, и другое?

Существует довольно много различных методов PowerShell для вывода информации в несколько мест. Давайте представим на мгновение, что по какой-то причине я хочу узнать, работает ли служба BitLocker, и что я хочу отобразить статус службы на экране, а также записать его в переменную. Одним из способов выполнения этой задачи было бы сделать что-то вроде этого:

$A = Get-Service BDESVC $A

Первая строка кода захватывает выходные данные командлета Get-Service (поскольку они связаны со службой BDESVC) и присваивает их переменной с именем A$. Вторая строка кода выводит содержимое переменной на экран. Таким образом, эти две строки кода соответствуют заявленным целям, отображая вывод команды на экране, а также записывая его в переменную.

Теперь давайте посмотрим, как то же самое можно сделать с помощью командлета Tee-Object. Командлет позволяет выводить вывод на экран и одновременно записывать либо в файл, либо в переменную. Вот пример команды:

Get-Service BDESVC | Тройник-объект - переменная A

Вы можете увидеть, как выглядит вывод команды на рисунке ниже. На снимке экрана также показано, что происходит, когда я вызываю переменную.

Еще один хитрый трюк

Итак, это ловкий трюк, но здесь происходит нечто большее, чем кажется на первый взгляд. Командлет Tee-Object можно вставить в середину конвейера команд. Другими словами, мое объявление переменной Tee-Object не должно быть концом команды. Я могу передать вывод на экран дополнительным командлетам так же, как если бы команды Tee-Object не существовало. Вот пример:

Get-Service BDESVC | Тройник-объект - переменная A | Select-Object Name, Status

Вы можете увидеть, что делает эта команда на рисунке ниже. Вы также можете видеть, что содержимое переменной не совсем соответствует тому, что отображается на экране, потому что я объявил переменную до того, как использовал командлет Select-Object.

Несмотря на то, что я обычно использую командлет Tee-Object в основном для определения переменных из конвейера команд, у него есть и другие применения. Точно так же, как вы можете использовать командлет Tee-Object для определения переменной, вы также можете использовать его для записи вывода команды в файл.

Синтаксис, используемый для этого, почти идентичен тому, что вы уже видели. Все, что вам нужно сделать, это заменить -Variable на -Filepath. Вы, конечно, также замените имя переменной на путь к файлу и имя файла, которые вы хотите использовать. В большинстве случаев путь и имя файла необходимо заключать в кавычки.

Чтобы показать вам, как это работает, давайте предположим, что вы хотите взглянуть на службу Bitlocker, как мы это делали раньше. Однако на этот раз мы хотим сбросить вывод команды в файл, а не записывать его в переменную. Команда для этого будет выглядеть примерно так:

Get-Service BDESVC | Tee-Object -FilePath «C:DataBitlocker.txt»

Точно так же, как мы можем использовать команду Tee-Object для объявления переменной из середины конвейера, мы также можем записать файл из середины конвейера. Вот один из моих ранних примеров, но модифицированный таким образом, чтобы он создавал файл, а не переменную.

Get-Service BDESVC | Tee-Object -FilePath «C:DataBitlocker.txt» | Select-Object Name, Status

Два по цене одного командлета

Одна из действительно крутых вещей, которые вы можете сделать с помощью команды Tee-Object, заключается в том, что вы можете использовать ее для одновременной записи двух файлов. Предположим на мгновение, что у вас есть сценарий PowerShell, который создает данные журнала. Давайте также представим, что, хотя самые последние данные регистрации представляют для вас наибольший интерес, более старые данные регистрации также имеют ценность. С помощью командлета Tee-Object мы можем создать два разных файла журнала. Один из этих журналов может содержать последние данные регистрации, а другой — совокупные данные регистрации. Возвращаясь к моему примеру службы Bitlocker, вот как может быть структурирована команда:

Get-Service BDESVC | Tee-Object -FilePath «C:DataCumulativeLog.txt» -Append | Исходящий файл C:DataNewLog.txt

Как видите, я использую командлет FilePath для создания совокупного журнала и командлет Out-File для создания нового файла журнала. На самом деле я мог бы использовать любую команду для создания файла журнала любого типа. Причина, по которой Tee-Object создает кумулятивный файл журнала, в данном случае связана с параметром -Append. Этот параметр указывает PowerShell добавить данные в существующий файл, а не просто перезаписывать существующий файл журнала новым файлом.

Tee-Object: отличная экономия времени

Командлет Tee-Object обладает большим потенциалом для упрощения написания сценариев PowerShell. Недавно я написал для этого сайта несвязанную статью о том, как использовать PowerShell, чтобы выяснить, на каком сервере Hyper-V размещена конкретная виртуальная машина. Я использовал командлет Tee-Object в этом конкретном скрипте, потому что это позволило мне избежать сложных сценариев.