Написать вывод: Как писать вывод по истории. Как начать писать выводы

Содержание

echo (вывод на экран) | Microsoft Docs

  • Статья
  • Чтение занимает 2 мин
  • Участники: 9

Были ли сведения на этой странице полезными?

Да Нет

Хотите оставить дополнительный отзыв?

Отзывы будут отправляться в корпорацию Майкрософт.

Нажав кнопку “Отправить”, вы разрешаете использовать свой отзыв для улучшения продуктов и служб Майкрософт. Политика конфиденциальности.

Отправить

В этой статье

Отображает сообщения или включает или отключает функцию вывода команд. При использовании без параметров echo отображает текущее значение эха.

Синтаксис

echo [<message>]
echo [on | off]

Параметры

Параметр Описание
[вкл. | выкл.] Включает или выключает функцию вывода команд. Команда по умолчанию включена.
<message> Задает текст, отображаемый на экране.
/? Отображение справки в командной строке.
Комментарии
  • echo <message>Команда особенно полезна при отключенном echo <message> . Чтобы отобразить сообщение, которое содержит несколько строк без отображения команд, можно включить несколько echo <message> команд после команды echo <message> в пакетной программе.

  • После выключения эхо Командная строка не отображается в окне командной строки. Чтобы отобразить командную строку, введите команду echo on.

  • Если используется в пакетном файле, Включение и вывод не влияют на параметр в командной строке.

  • Чтобы предотвратить вывод определенной команды в пакетном файле, вставьте @ знак перед командой. Чтобы предотвратить вывод всех команд в пакетном файле, включите команду echo off в начале файла.

  • Чтобы отобразить символ канала ( | ) или перенаправления (

    < или > ) при использовании |, используйте знак крышки ( ^ ) непосредственно перед символом канала или перенаправления. ).

Примеры

Чтобы отобразить текущее значение echo , введите:

echo

Чтобы вывести на экран пустую строку, введите:

echo.

Примечание

Не включайте пробел перед точкой. В противном случае вместо пустой строки отображается точка.

Чтобы запретить вывод команд в командной строке, введите:

echo off

Примечание

Когда эхо отключено, Командная строка не отображается в окне командной строки. Чтобы снова отобразить командную строку, введите команду echo on.

Чтобы предотвратить отображение на экране всех команд в пакетном файле (включая команду echo off ), в первой строке типа пакетного файла:

@echo off

Команду echo можно использовать как часть оператора If . Например, чтобы найти в текущем каталоге любой файл с расширением. rpt и вывести сообщение при обнаружении такого файла, введите:

if exist *.rpt echo The report has arrived.

Следующий пакетный файл ищет в текущем каталоге файлы с расширением .txt File и выводит сообщение с указанием результатов поиска:

@echo off
if not exist *.txt (
echo This directory contains no text files.
) else (
   echo This directory contains the following text files:
   echo.
   dir /b *.txt
   )

Если при выполнении пакетного файла не найдены .txt файлы, отображается следующее сообщение:

This directory contains no text files.

Если при выполнении пакетного файла будут обнаружены .txt файлы, отображаются следующие выходные данные (в этом примере предполагается, что файлы File1.txt, File2.txt и File3.txt существуют):

This directory contains the following text files:
File1.txt
File2.txt
File3.txt

Дополнительные ссылки

Как написать хороший отзыв — Помощник 2ГИС

Отзывы в 2ГИС помогают пользователям сделать выбор, а компаниям — получить фидбэк о качестве своей работы.

О том, как пользоваться интерфейсом 2ГИС, чтобы написать отзыв, можно прочитать в статье «Как оставить отзыв о компании». А полные правила публикации отзывов находятся в разделе «Правовая информация».

Правила написания отзывов построены на одном принципе: отзывы — это конструктивные мнения реальных клиентов фирм.

Мы составили список рекомендаций о том, как поделиться опытом в 2ГИС и сделать отзыв ещё полезнее.

Опишите больше подробностей и фактов

Подробно опишите положительные и отрицательные стороны, перечислите плюсы и минусы. Например, после бизнес-ланча в новом заведении можно объяснить причины, по которым вы выбрали ресторан, описать, что понравилось в меню и обслуживании, а что — нет.

Пишите о собственном опыте

Пишите о личном клиентском опыте, а не о самой компании. Если вы сами отказались от услуг фирмы, например, из-за высокой цены, неудачного интерьера офиса, условий обслуживания или долгих сроков, писать отзыв не стоит.

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

Не пишите отзывы с чужих слов и не оценивайте услугу, которую оказали другому человеку. Лучше предложите ему самому опубликовать собственный отзыв.

Исключение — опыт маленьких детей и пожилых людей, которые не могут написать отзыв сами. Если вы встретили отзыв без клиентского опыта, пожалуйста, отправьте жалобу — модераторы его проверят его.

Пишите ясно, приводите интересные детали

Разбейте текст отзыва на абзацы, чтобы его было удобнее читать другим пользователям. Длинные перечисления можно написать в виде списке с маркерами. В конце отзыва, после описания всех деталей, плюсов и минусов, лучше сделать вывод.

Соблюдайте правила русского языка: старайтесь писать грамотно, используя знаки препинания, не злоупотребляйте прописными буквами. Помните, что в отзывах запрещены ссылки на другие сайты, оскорбления и ругательства.

Иллюстрируйте отзывы фотографиями

Фото делает отзыв ещё более информативным, полезным и красивым. Кроме того, снимки из заведения подтверждают, что автор отзыва его посещал, и делают отзыв более достоверным. Фотографии к отзыву можно прикрепить и в приложении, и в онлайн-версии 2ГИС, в том числе при редактировании ранее написанных отзывов.

Не будьте предвзяты

Не рекомендуется писать отзывы о собственной компании или о компаниях конкурентов. Такие отзывы могут быть необъективны, поэтому модераторы их удалят.

Если вы заметили подозрительный отзыв в карточке компании, пожалуйста, отправьте жалобу — в 2ГИС его проверят.

Не дублируйте отзывы в 2ГИС и на Флампе

Отзывы из Флампа автоматически попадают в 2ГИС. Если оставить два одинаковых отзыва на обеих площадках, один из них модераторам придётся удалить. К тому же для формирования рейтинга компании должна учитываться только одна из оценок — или на 2ГИС, или на Флампе.

Не публикуйте уже отклонённый отзыв

Если отзыв заблокирован, значит он нарушает правила. Узнать причину блокировки можно в профиле: в приложении 2ГИС зайдите на вкладку «Мой 2ГИС», откройте отзыв и нажмите на отметку «Удалён модератором».

Чтобы отзыв был опубликован, его следует переписать так, чтобы он соответствовал правилам 2ГИС. При многократных попытках отправить заблокированный отзыв аккаунт может быть заблокирован.

Важно: 2ГИС не удаляет отзывы по просьбам компаний, но проверяет отзывы, на которые поступают жалобы. Единственная причина, по которой отзыв в итоге может быть удалён, — если он нарушает правила. По вопросам, связанным с блокировкой отзывов, можно связаться по адресу [email protected]

Подтвердите клиентский опыт

Компания, магазин, ресторан или другое место, о котором написан отзыв, может запросить у автора дату и время посещения, попросить чек, описать заказ или назвать последние цифры номера телефона, чтобы убедиться, что автор был клиентом.

Если автор отзыва не может предоставить информацию в ответ на уточняющий запрос, отзыв скрывается и перемещается в раздел «Неподтверждённые». В таком случае автору отзыва надо ответить на запрос компании в течение четырёх дней. Чтобы отзыв остался в основной ленте, его можно отредактировать, опубликовать какое-либо подтверждение в комментарии под отзывом или отправить дополнительную информацию на [email protected]

Проверьте адрес компании перед публикацией отзыва

Перед публикацией отзыва о сетевых магазинах и кафе лучше проверить адрес филиала — это поможет избежать оценки другого подразделения этой же организации.

Отзыв, который написан о филиале по ошибке, придётся удалить, потому что подтвердить его посещение и клиентский опыт будет невозможно.

Отзывы следует оставлять в карточках компаний, а не зданий, в которых они работают.

Обращайте внимание на подозрительные отзывы

Об отзывах, которые нарушают правила, можно сообщить в 2ГИС. Чтобы пожаловаться на отзыв или прикреплённое к нему фото, откройте отзыв, нажмите на три точки в правом верхнем углу и далее → «Пожаловаться». Опишите суть жалобы и нажмите «Отправить». Модераторы получат ваше сообщение, и если жалоба подтвердится — подозрительный отзыв удалят.

Если вам кажется, что в карточке компании есть накрутки, пожалуйста, отправьте жалобы на каждый отзыв, который кажется подозрительным. Модераторы проверят их и заблокируют, если информация подтвердится.

Вывод средств по письменному заявлению – Помощь

Этот способ подойдёт в том случае, если оплата производилась физическим лицом. Отправить заявление можно по почте и с помощью СЭДО (системы электронного документооборота).

Отправка заявления по почте

  1. 1.

    Заполните и подпишите заявление на вывод средств:

  2. Отправка заявления через ЭДО

    Если у вас подключён ЭДО (электронный документооборот), вы можете отправить заявление через эту систему. Подробнее об ЭДО читайте в статье.

    Нерезиденты НЕ могут отправлять документы с помощью СЭДО.

    1. 1.

      Заполните заявление на вывод средств и подпишите его ЭЦП.

    2. 2.

      Отправьте заявление в рамках СЭДО как документ (не как письмо!).

Способ подойдёт тем, кто произвёл оплату с расчётного счёта юридического лица или ИП. Отправить заявление можно по почте и с помощью СЭДО (системы электронного документооборота).

Отправка заявления по почте

  1. 1.

    Заполните заявление на вывод средств на бланке организации и заверьте его печатью и подписью уполномоченного лица. Бюджетным организациям в банковских реквизитах нужно указать КБК

    и ОКТМО.

  2. 2. Отправьте нам скан-копию заполненного заявления в рамках заявки в службу поддержки. Оригинал — на почтовый адрес.

Средства будут отправлены на возврат в течение 14 дней после получения скан-копии заявления.

Наш почтовый адрес: 123007 Москва, а/я 87, ООО «Регистратор доменных имён РЕГ.РУ».

Отправка заявления через ЭДО

Если у вас подключён ЭДО (электронный документооборот), вы можете отправить заявление через эту систему. Подробнее об ЭДО читайте в статье.

Нерезиденты НЕ могут отправлять документы с помощью СЭДО.

  1. 1.

    Заполните заявление на вывод средств на бланке организации и заверьте его печатью и подписью уполномоченного лица. Бюджетным организациям в банковских реквизитах нужно указать КБК и ОКТМО.

  2. 2.

    Отправьте заявление через СЭДО как документ (не как письмо!).

  3. Заключение – Сравнительная история нефтезависимых экономик конца XX — начала XXI века – Московский Центр Карнеги

    Содержание

    Сравнительный анализ представленных стран

    Представленные в нашем обзоре страны условно можно разделить на четыре группы исходя из сочетания двух параметров: 1) объема обеспеченности ресурсом, то есть подушевого уровня добычи нефти, и 2) эффективности экономического использования ресурса, то есть отношения объемов добычи нефти к общему ВВП страны.

    Для оценки размеров удобнее всего измерять первый параметр в барр./чел. в год, а второй — в барр./ВВП, где ВВП выражен в миллионах долларов.

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

    Результаты такой кластеризации представлены на рис. 1 и 2.

    Норвегия, Объединенные Арабские Эмираты и Саудовская Аравия образуют группу стран с очень высокой обеспеченностью ресурсом (первая группа). При этом эффективность его использования у них разная: относительно высокая у Норвегии, средняя у ОАЭ и низкая у Саудовской Аравии.

    Ангола и Азербайджан представляют группу стран со средней обеспеченностью ресурсом и очень низкой эффективностью его экономического использования (вторая группа).

    Венесуэла, Иран, а также оставшаяся за рамками данного исследования Россия попадают в группу стран со средней обеспеченностью ресурсом и средней эффективностью его использования (третья группа).

    Наконец, Мексика, Индонезия и, как это ни покажется странным, Нигерия попадают в группу малообеспеченных ресурсом стран с высокой эффективностью использования ресурса (четвертая группа).

    Первая группа: Норвегия, Объединенные Арабские Эмираты, Саудовская Аравия

    Высокообеспеченные ресурсами страны из нашего исследования, казалось бы, отличаются друг от друга по всем возможным параметрам начиная с политического устройства. Норвегия — демократическая страна, чему нисколько не мешает наличие монарха. В Объединенных Арабских Эмиратах и Саудовской Аравии правят авторитарные режимы. При этом у Норвегии и ОАЭ сравнимая эффективность использования ресурса, близкие цифры ВВП на душу населения, медианных доходов домохозяйств, темпов роста ВВП и других экономических показателей. По некоторым же признакам либерально-демократическая Норвегия уступает авторитарным ОАЭ. Это наблюдение дает нам в руки грубый, но полезный инструмент анализа, позволяющий все различия между ОАЭ и Норвегией считать незначимыми для экономического развития ресурсных стран. В то же время признаки, отличающие Норвегию и ОАЭ от Саудовской Аравии, можно считать значимыми.

    Как видно из представленного (очень грубого) факторного сравнения, существенное различие между Норвегией и ОАЭ с одной стороны и Саудовской Аравией с другой определяется всего двумя группами факторов: уровнем личных свобод и открытостью экономики. В то же время Норвегия и ОАЭ принципиально различаются также двумя факторами. Во-первых, типом государственного устройства: демократия против авторитарной системы правления. Во-вторых, системой пролиферации доходов: государство всеобщего благоденствия c высокими налогами против фактически безналогового государства с высокими субсидиями.

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

    Вторая группа: Азербайджан, Ангола

    Во второй группе представлены две страны, эффект «ресурсного проклятия» в которых выражен особенно сильно. Если часть проблем Анголы можно было бы списать на колониальную историю, неразвитость инфраструктуры и, главное, на гражданскую войну, то Азербайджану сложно апеллировать к тяжелому прошлому. Как часть СССР, эта страна подошла к 1991 году почти с теми же стартовыми условиями, что и, например, Казахстан или Грузия, но только со значительными запасами углеводородов. Для анализа нам необходимо увидеть общие свойства Анголы и Азербайджана — причем именно те, которые отличают их от стран с более успешной историей использования минеральных ресурсов.

    Общие черты экономики Азербайджана и Анголы — неразвитость инфраструктуры, относительная закрытость экономики, ограничение прав и свобод и авторитарность власти. Ангола, с менее авторитарной властью и большей свободой в экономике, оказывается значительно эффективнее Азербайджана в создании «ненефтяного» ВВП.

    Кроме уже названных проблем для экономики Азербайджана и Анголы характерны:

    • неспособность сохранить избыточные доходы, уход большей части собираемой ренты на бюджетные расходы;
    • повышенная милитаризация: наличие спорных территорий, участие в военных конфликтах, выделение значительных средств на военные расходы;
    • высокий уровень коррупции.

    Вышеописанные признаки встречаются и у более эффективных стран со средней добычей углеводородов на душу населения: Ирана, Венесуэлы, Нигерии, России. Однако именно в Анголе и Азербайджане эти особенности выражены столь явно[1].

    Третья группа: Венесуэла, Иран

    В третью группу мы включили Венесуэлу и Иран — страны со средними уровнями и эффективности, и добычи углеводородов. Под средним уровнем эффективности мы подразумеваем тот, что соответствует Объединенным Арабским Эмиратам. Существенное отличие ОАЭ от стран третьей группы состоит только в объемах добычи нефти и газа на душу населения. Но уровень жизни в странах первой и третьей группы различается очень сильно. Венесуэла и Иран страны бедные. И если в Иране режим все еще держится на авторитарности, жестком религиозном контроле и архаичных традициях социального устройства и производства, то в Венесуэле назревают существенные перемены.

    Как видим, страны третьей группы объединяются только субсидионным характером пролиферации избыточных доходов и закрытостью экономик, которая вообще характерна для всех исследованных стран с низкой «нефтяной эффективностью»[2].

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

    Четвертая группа: Мексика, Индонезия, Нигерия

    Эти страны отличаются не только высокой диверсификацией экономики от сырьевого сектора, но и относительно низким уровнем подушевой добычи углеводородов. Нельзя поэтому сказать с уверенностью, что служит здесь главной причиной успешной диверсификации — эффективная экономическая политика или не слишком высокая обеспеченность ресурсами.

    Так или иначе, для всех представленных стран характерны довольно высокая открытость экономики и либеральная рыночная структура. Возможно, именно сочетание этих двух факторов позволяет им успешно диверсифицировать экономику.

    Наконец, не надо забывать, что диверсификация от минеральных ресурсов — характеристика относительная, использование ее в странах с низкой подушевой добычей ресурсов может давать ложное представление об экономической успешности. Так происходит, например, с Нигерией, где ВВП на душу населения составляет чуть менее 3000 долларов (немногим ниже Анголы). Тем не менее в нашем анализе Нигерия попадает в «успешные» страны. Для процветания при низком объеме ресурсов на душу населения недостаточно хорошо проведенной диверсификации. Необходимо еще обеспечить высокие темпы роста независимой от ресурсов экономики.

    Примечания

    1 Для сравнения: в России экономика достаточно либеральна, а стерилизация избыточных доходов от нефти и газа эффективна.

    2 Кроме ОАЭ, если не считать открытостью использование китайскими корпорациями территории Анголы. Но сравнительная неэффективность Эмиратов объясняется скорее просто переизбытком нефти.

    Перенаправление ввода и вывода в приложении «Терминал» на Mac

    С помощью командной строки можно перенаправлять потоки входных и выходных данных с команды на файл или другую команду.

    Перенаправьте вывод из команды, если хотите сохранить результаты выполнения команды в файле для дальнейшего использования. Перенаправьте ввод команды на получение готовых данных из файла, если не хотите вводить входные данные вручную.

    Для перенаправления ввода и вывода используются следующие символы:

    Перенаправление

    Описание

    >

    Используйте правую угловую скобку, чтобы перенаправить выходные данные команды в файл.

    <

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

    >>

    Используйте две правые угловые скобки, чтобы добавить вывод из команды в файл.

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

    Например, следующая команда передает отформатированное содержимое man-страницы zsh инструменту grep, который ищет в этих данных строки, содержащие слово commands. Результатом является список строк с заданным текстом, а не целая man-страница.

    % man zsh | grep commands

    Стандартные потоки ввода/вывода:

    • stdin. Стандартный поток ввода — это поток, из которого команда получает входные данные. По умолчанию входные данные вводятся через интерфейс командной строки. Вы можете перенаправить вывод из файлов или других команд в поток stdin.

    • stdout. Стандартный поток вывода — это поток, куда команда отправляет выходные данные. По умолчанию команда выводит данные в командную строку. Вы можете перенаправить вывод с командной строки на другие команды и инструменты.

    • stderr. Стандартный поток ошибок — это поток, куда отправляются сообщения об ошибках. По умолчанию ошибки отображаются в командной строке вместе со стандартным потоком вывода.

    Подробнее о перенаправлении см. на man-странице команды zsh.

    Социальные сети: польза и вред



    Чем же так манят нашу молодёжь социальные сети? Рассмотрим положительные и отрицательные стороны общения в соц. сетях.

    Положительные стороны социальных сетей:

    1. Скорость поиска. В социальных сетях можно без проблем найти нужное видео, музыку, человека, а также просто отыскать единомышленников. Регистрируясь в социальной сети, пользователь сообщает свои имя и фамилию, а также другие данные – возраст, учебные заведения, контактные телефоны. Это позволяет в считанные секунды найти любого человека, при условии, что он указал достоверные сведения о себе. Это очень весомый плюс – ведь раньше для того, чтобы найти друзей детства или одноклассников требовалось гораздо больше времени.

    2. Простота общения и обмена информацией. Конечно же, у каждого из нас есть мобильный телефон, и мы можем обмениваться информацией посредством смс и ммс сообщений. Но ведь на это уходит немалое количество денег. Гораздо удобнее пересылать данные в соц. сетях. Имея аккаунт в социальной сети, человек находится в курсе всего, что происходит с его друзьями, он может зайти на страничку любого интересующего его человека, посмотреть фотографии, прокомментировать новости или просто пообщаться. Это очевидное достоинство соц. сетей – сегодня общаться стало гораздо проще и удобнее.

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

    Отрицательные стороны социальных сетей:

    1. Расход большого количества времени. Для кого-то соц. сети – это отличный шанс «убить» время, а для кого-то – это просто потраченные впустую часы. Ведь это время можно провести с гораздо большей пользой: встретиться с друзьями, приготовить вкусный ужин или же заняться самообразованием.

    2. Отрешение от реального мира. В социальных сетях мы позиционируем себя несколько иначе, нежели в жизни. Опираясь на современные исследования в области Интернет – общения, можно сказать, что 70% активных посетителей социальных сетей приукрашивают свою жизнь. Кроме того, возможность изменить реальность и предстать в социальной сети богатым и успешным также многих прельщает. В итоге есть риск настолько вжиться в созданный виртуальный образ, что, так сказать, вернуться вовремя на землю не всегда получается.

    3. Деградация личности. Если обратить внимание на речь чрезмерно активных пользователей социальных сетей, то можно заметить бессмысленность большинства их разговоров и присутствие в них непонятных обычным людям слов, типа «лайкнуть», «юзать», «лол» и т.д.

    4.. Потеря навыков социального общения. Подмена реального общения ведет к потере чувства реальности и навыков социального общения. В живом разговоре нельзя поставить смайл. Понятия «добавить в друзья», «удалить из друзей», создают ощущение, что в реальной жизни так же просто строятся отношения, а это не так. Добавь на страницу свечу памяти по погибшим, добавь георгиевскую ленточку, гвоздику и т.д. в честь Дня Победы. Вместо реальной гвоздики ветеранам, вместо активной помощи благотворительным организациям и пострадавшим людям – человеку в сети кажется, что он, добавив картинку, сделал дело.

    5. Вероятность возникновения зависимости. Соц. сети обладают большим аддиктивным потенциалом, т.е. значительным риском возникновения зависимости. Особенно подвержены этому подростки, у которых отсутствие доступа в Интернет может вызвать настоящую психическую «ломку».

    6. Социальные сети — поле деятельности для мошенников и недоброжелателей. Не многие задумываются, что размещение чрезмерного количества фотографий, наиболее подробных данных о себе, может обернуться против них.

    7. Вред здоровью. Постоянное присутствие в соц. сети может нанести определенный вред здоровью. Многочасовое сидение за компьютером может привести к снижению зрения и гиподинамии.

    8. Потеря мотивации к работе. Человек, попавший в зависимость от социальных сетей, становится менее активным. Сегодня на многих предприятиях вход сотрудников в соц. сети недоступен, так как подобное общение сильно отвлекает от работы. ъ

    Исходя из всего написанного выше, можно сделать вывод: Социальные сети не несут в себе вреда, если пользоваться ими в меру.

    ПОМНИТЕ! Активное общение в социальных сетях является лишь дополнением к полноценному живому общению. Нужно уметь брать от социальных сетей только хорошее и отсеивать плохое!

    Get-PowerShellBlog: давайте убьем Write-Output

    Думаю, пора навсегда забыть о нашем старом друге Write-Output . Правильно, Write-Output , а не Write-Host . Вам определенно не следует использовать Write-Host вне функций, начинающихся с глагола Show- в консольных приложениях PowerShell, но я здесь не для того, чтобы убивать Write-Host . Нет, моя цель Write-Output .

    Что это за сумасшествие, о котором я говорю? Что ж, если бы я вернулся во времени на 10 месяцев назад и сказал себе не использовать Write-Output , я бы подумал, что мое будущее «я» сошло с ума.На самом деле, мой путь к убийству Write-Output начался примерно в это же время. В /r/PowerShell был пост (к сожалению, я не могу найти его в своей истории), где я «исправлял» кого-то за то, что он не использовал Write-Output . Это побудило другого пользователя связать меня с этим обсуждением. Сначала я отверг эту идею, но со временем я ее принял. И сегодня, я думаю, я был сумасшедшим, что не убил его раньше.

    То, что я здесь говорю, не будет новым или революционным. Моя единственная надежда с помощью этого поста — показать другим проблемы с Write-Output и способствовать его упадку.

    Какие у меня проблемы с Write-Output ? У меня есть три опасения по поводу использования Write-Output : производительность, «безопасность» и «ложное чувство безопасности».

    Прежде чем вы начнете, имейте в виду, что это не тема для ознакомления с PowerShell. Этот пост был написан для опытных пользователей PowerShell и тех, кто предоставляет рекомендации и обучение для начинающих пользователей PowerShell. Кроме того, этот пост не конкретно о выводе на консоль, а об использовании команды Write-Output в целом и ее обычном использовании для «помещения объектов в конвейер» (т.грамм. для «возвращения» объектов из функции). Большинство из них применимо независимо от того, попадают ли объекты в конечном итоге на консоль или нет. Единственным разделом, связанным с выводом на консоль, является раздел «Текстовый вывод». Даже в этом случае выходные данные для целевых сценариев чаще представляют собой файл журнала, чем консоль.

    Первая причина, по которой я спрятал Write-Output в неизвестном месте, заключается в том, что у него есть проблемы с производительностью. Это медленно по сравнению с размещением объектов непосредственно в потоке вывода. Разница измерима на больших итерациях.У меня был процесс анализа разрешений для каждого элемента на наших сайтах OneDrive для бизнеса, и время выполнения увеличилось с нескольких дней до нескольких часов только за счет удаления всех вызовов Write-Output . Уже существовало сильное распараллеливание, но с таким количеством объектов и кучей вспомогательных функций, действующих на них, было выполнено большое количество вызовов Write-Output для каждого элемента, умноженное на миллиарды элементов, которые ему приходилось анализировать.

    Как может то, что просто помещает объекты в конвейер, быть таким медленным? Во-первых, это не , что медленный.По сравнению с разницей между ускорителем типа [PSCustomObject] и использованием New-Object и Add-Member , которые на несколько порядков медленнее, размещение объектов непосредственно в конвейере по сравнению с использованием Write-Output является только немного медленнее. Но есть несколько причин.

    Во-первых, существуют затраты, связанные с установкой и демонтажем, необходимыми для вызова. Если вы посмотрите на исходный код Write-Output , то не все так сложно.По сути, это оболочка для метода Cmdlet. WriteObject() . Но каждый вызов влечет за собой затраты на выполнение этого переноса.

    Во-вторых, если вы правильно кодируете и создаете функции, которые Do One Thing , вы получите кучу вызовов Write-Output , если вы используете его для помещения объектов в конвейер. У вас может быть ваш управляющий скрипт, вызывающий функции модуля, вызывающий приватные функции несколько раз, а затем цикл, повторяющийся 100 или 1000 раз.Эта разница в скорости быстро увеличивается.

    Наконец-то совсем лишнее навороты! Write-Output является оболочкой Cmdlet.WriteObject() . Но Cmdlet.WriteObject() уже везде вызывается по умолчанию. Так что это просто вставка вызова, который позже все равно будет сделан снова. С таким же успехом я мог бы съездить в магазин и вернуться, прежде чем ехать в магазин, если я хочу позвонить, используя Write-Output , эффективно.

    Но не верьте мне на слово. Вы можете проверить это сами.

    «Метод записи на запись: {0} ‘-F -F (

    мера-команда {

    1..1000 | foreach-объект {

    $ person = [pscustomobject] @ {

    firstname =’ bob ‘

    LASTNAME = ‘TESTERTON’

    AGE = 38

    }

    }

    Repicount $ Person

    }

    } | Выбор объекта-Expandproperty Totalmilliseconds

    )

    ‘объявлен и прошедший метод: {0}’ – f (

        Measure-Command {

            1..1000 | Foreach-object {

    $ person = [pscustomobject] @ {

    firstname = ‘testerton’

    age = 38

    }

    $ Person

    }

    } | Select-Object -ExpandProperty TotalMilliseconds

    )

    ‘Прямо к конвейерному методу: {0}’ -f (

        Measure-Command {

            1..1000 | Foreach-object {

    [pscustomobject] @ {

    первое имя = ‘BOB’

    LASTNAME = ‘TESTERTON’

    AGE = 38

    }

    }

    } | Select-Object -ExpandProperty TotalMilliseconds

    )

    В приведенном выше коде показаны три метода создания [PSCustomObject] и помещения его в конвейер 1000 раз. На моем компьютере я получаю следующие результаты:

    Метод записи-вывода: 164.9981

    Объявленный и переданный метод: 75.5935

    Прямой метод конвейера: 50.7954

    Использование Write-Output в 3 раза медленнее, чем непосредственное создание объекта и отправка в конвейер. Даже использование метода «Объявлено и пройдено» намного быстрее. Это простой тест, но вы можете видеть, как он добавляет больше логики, разделения кода и итераций, которые вы используете. В простом сценарии это может не иметь большого успеха, но в чем-то вроде процесса OneDrive, о котором я упоминал в начале этого раздела, это может иметь огромное влияние.

    Следующая причина, по которой Write-Output   зарегистрировалась в Motel Deep 6, — это «безопасность» и стабильность. На самом деле это две причины, связанные общей проблемой. Основная проблема заключается в том, что Write-Output не является защищенным ключевым словом в PowerShell. Это означает, что команда может быть перезаписана функцией или псевдонимом с таким же именем, имеющим более высокий приоритет команды.

    «Безопасность»

    Возможность переноса, затирания и/или прокси Запись-вывод — палка о двух концах.Если вы всегда используете Write-Output для размещения объектов в конвейере, вы можете сделать несколько действительно изящных трюков с ведением журнала, телеметрией и отладкой, обернув команду. Вот пример:

    функция записи {

    [командлетка (

    [cmdletbinding (

    helpuri = ‘https://go.microsoft.com/fwlink/?LinkiD=113427’,

    RemotingCapability = ‘none’

    ) ]

    paral (

    [Параметр (

    Обязательный = $ true,

    Положение = 0,

    ValueFreompipipieline = $ TRUE,

    ValueFromremramingsarGuments = $ TRUE

    )]

    [Allowerull)]

    AlseUttyCollection ()]

    [Psobject []]

    $ {Inputobject},

    [Switch]

    $ {Noeberate})

    Начало {

    Try {

    $ Outbuffer = $ null

    , если ($ null

    PSBoundПараметры. TryggetValue («Outbuffer», [REF] $ OUTBUFFER)) {

    $ PSBoundparameters [‘outbuffer’] = 1

    }

    $ WROPHOWCMD = $ EXECUTIONCONTEXT.invokeCommand.getCommand (

    ‘Microsoft.PowerShell.UTILITY \ НАПИСАТЬСЯ -OUTPOUT ‘,

    [System.management.automation.commandtypes] :: cmdlet

    )

    $ ScriptCMD = {& $ WROPHEPMD @PSBoundParameters}

    $ steppablepipeline = $ scriptcmd.GetStepplePipeline ($ myinvocation.commandorigin)

    $ steppablepipeline.begin ($ pscmdlet)

    } Catch {

    RUB

    }

    }

    Процесс {

    $ Timestamp = Get-Date-format o | foreach {$_ -replace “:”, “.”}

            $LogFile = ‘{0}\{1}-object.xml’ -f $ENV:LOCALAPPDATA, $TimeStamp

            $LogObject = [PSCustomObject]@ {

    Дата Дата = Get-Date

    Объект = $ {Inputobject}

    callstack = get-pscallstack

    pscmdlet = $ pscmdlet

    }

    $ logobject | Export-Clixml -Path $LogFile

            try {

                $steppablePipeline. Процесс ($ _)

    } Catch {

    бросок

    }

    }

    }

    END {

    TRY {

    $ STEPPABLEPIPELINE.end ()

    } Catch {

    RUB

    }

    }

    <#

    .forwardhelptargetname Microsoft.PowerShell.UTILITY \ PROTION-OPTICE

    .FORWARDHELPCATHERY CDRDLET

    #>

    }

    Это будет действовать точно так же, как вывод записи , за исключением того, что, в дополнение к размещению объекта в конвейера, он также записывает дату, время, содержимое объекта, стек вызовов и $PSCmdlet в XML-файл.Это здорово видеть, что все происходит, где, когда и почему… но это не просто потрясающе с точки зрения разработчика и телеметрии. Другое острие меча — эксфильтрация данных. Export-Clixml с таким же успехом может быть вызовом REST API, передающим данные в формате JSON на удаленную конечную точку злоумышленника.

    Причина, по которой это проблема «безопасности» (с кавычками), а не проблема безопасности (без кавычек), заключается в том, что если у злоумышленника есть возможность сделать это, у вас, вероятно, есть более серьезные проблемы, чем эксфильтрация данных через PowerShell. Это также не единственный способ достичь этой цели. Тем не менее, с плодотворным использованием Запись-Вывод и тот факт, что почти все с тем же именем будет иметь более высокий приоритет команды, делает Запись-Вывод мягкой, легкой и надежной целью. Я не пытаюсь намекнуть, что это угроза безопасности на уровне «остановить прессу», но ее следует учитывать.

    Стабильность

    Начиная с Запись-Вывод может быть затерта, в зависимости от этого это может привести к проблемам со стабильностью.Вам нужно беспокоиться не только о хакерах. Это также вводит в заблуждение пользователей и разработчиков. Кто-то может прочитать мой пост, увидеть пример выше и подумать, что было бы здорово реализовать это в своей среде, чтобы увидеть, что происходит. Предположим, я понятия не имею, что делаю (это безопасное предположение), и этот код приводит к тому, что 1 из 5 объектов исчезает в эфире. Если ваш модуль или код использует Write-Output, пользователь теперь представил ситуацию, когда ваш код внезапно содержит ошибки и не работает.

    Это не для того, чтобы обвинять разработчиков, использующих Write-Output . Нет, вина полностью лежит на пользователе за то, что он был достаточно сумасшедшим, чтобы сделать это. Но это то, что нужно учитывать. Если вы посмотрите на такие проекты, как Pester и модули Microsoft PowerShell, вы увидите, что многие из них включают средства защиты от такого поведения, гарантируя, что такие команды, как Write-Output , являются правильными. (Вероятно, это лучшая практика, которую следует применять массово.) Однако в большинстве проектов не нужно дважды думать об использовании основных команд PowerShell.Вам также нужно беспокоиться не только о глупых пользователях. Глупые разработчики могут очень легко создать функцию в глобальной области видимости для перехвата Write-Output при загрузке модуля.

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

    Резюме проблем безопасности и стабильности

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

    Последняя причина, по которой Write-Output носит новые цементные туфли во время сна с рыбами, заключается в том, что это дает «ложное чувство безопасности» для знания того, где генерируется вывод.

    Один из принципов программирования, который хорошо подходит для написания кода, гласит: «явное лучше, чем неявное». Эта аксиома укоренилась во многих из нас, и на то есть веские причины. Неявные вещи, как правило, со временем становятся сломанными непознаваемыми вещами. Сохранение действий в вашем коде явным помогает сохранить историю и поток внутри кода, чтобы вы и другие могли вернуться к нему позже и узнать, что происходит.

    Этот принцип, однако, расходится с моей «кодецидной» тирадой против Write-Output . Отсутствие команды на картинке делает код более «неявным», а не «явным». Одна фраза, которая пронизывает сообщество PowerShell, — «неявный Write-Output ». Он используется для описания следующего:

    $ProcessNames = foreach ($Process in (Get-Process)) {

        $Process.Name

    }

    Можно сказать, что $Process.Name «отправляется». в конвейер с неявным Write-Output ».Подразумевается, что на самом деле выполняется следующий код:

    $ProcessNames = foreach ($Process in (Get-Process)) {

        Write-Output $Process. name

    }

    Однако это не так. В первом блоке Write-Output никогда не вызывается. Если вы помните, ранее я указывал, что Write-Output является оболочкой для Cmdlet.WriteObject() . Именно так и называется, а не Write-Output .

    Что здесь более важно, так это принцип или сущность «неявной Запись-Вывод », а не фактическая внутренняя работа.Причина, по которой первый блок кода часто считается неправильным, заключается в том, что действие по записи объекта в поток вывода подразумевается, а не указывается явно. Как правило, неправильно использовать «неявный» код вместо «явного», так что эти люди правы, верно?

    Неправильно! В том же коде вы найдете авторов, делающих это, не моргнув глазом:

    $ProcessNames = ‘powershell’, ‘mmc’

    $RunningProcesses = foreach ($ProcessName in $ProcessNames) {

        Get-Process -Name $ProcessName

    }

    Результаты Get-Process неявно отправляются в конвейер. В их мире для согласованности им нужно было бы сделать что-то вроде этого:

    $ProcessNames = ‘powershell’, ‘mmc’

    $RunningProcesses = foreach ($ProcessName в $ProcessNames) {

        $Results = Get-Process -Name $ProcessName

        Write-Output $Results

    }

    Итак, какое отношение это имеет к «ложному чувству безопасности»? Суть того, к чему обращается «неявный Write-Output », заключается в том, что явное использование Write-Output дает понять, что цель состоит в том, чтобы отправить объекты в поток вывода и сделать их доступными для поиска в коде.Однако этот принцип неверен в контексте PowerShell, что приводит к ложному чувству безопасности в отношении намерения и местоположения отправки объектов в конвейер.

    Я не являюсь специалистом в области CS, поэтому я не знаю всех правильных терминов для различных концепций программирования, поэтому, если я ошибаюсь в этой части, пожалуйста, поправьте меня. PowerShell имеет в основном три типа операторов: определения, назначения и «помещение объектов в конвейер». Определения — это такие операторы, как Function , Class и т. д.Они используются для определения фрагмента кода.

    .

    Все остальное — «постановка объектов на конвейер». Правильно, ВСЁ ОСТАЛЬНОЕ. Неважно, как вы его покрасите или назовете, все остальные операторы в PowerShell помещают объекты в конвейер.Эти объекты могут быть несуществующими ( [Void], $Null, пустых коллекций и т. д.) , но в конце все они передаются Cmdlet.WriteObject() .

    Get-Process

    1000

    5 + 10

    ‘Это строка’

    ‘Это {0}’ -f $ test

    $ процессы

    вывод записи $

    $object.Method()

    [PSCustomObject]@{Property = ‘Value’}

    Все это можно резюмировать как «сделать что-то и поставить это в конвейер».Это делает все эти операторы связанными по своему результату независимо от выполняемых ими действий.

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

    Вот откуда берется «Ложное чувство безопасности». Наличие Write-Output дает нам то теплое и уютное чувство, которое return часто дает в других языках. Однако независимо от того, что мы делаем, вывод может быть помещен в конвейер любой строкой, которая не является присваиванием или определением. Если мы заметим, что код создает более одного объекта, Write-Output не поможет нам отследить мошеннический код.Конечно, это может помочь нам узнать, откуда, по нашему мнению, должен поступать вывод, но насколько нам известно, Write-Output может выдавать [Void] , а весь реальный вывод находится в середине некоторого конвейера несколькими строками выше. . Или автор вполне мог иметь в виду, что крайний случай должен возвращать более одного объекта, и отсутствие Write-Output для таинственного объекта не указывает на отсутствие у них намерения. Кроме того, Write-Output может находиться в середине или в начале конвейера и помещать объекты в этот конвейер и фактически не возвращать объекты из блока кода.

    Мне было очень тяжело это принять. Все, чему я научился в своем опыте кодирования, требует от меня ясности. Но с Write-Output это может принести больше вреда, чем пользы в PowerShell. Что мне нужно было сделать, так это принять жадный характер конвейера PowerShell и отказаться от принципа «явное лучше, чем неявное» в этом случае. Это по-прежнему хороший принцип для всех остальных, но явно не панацея.

    Надеюсь, я проделал хорошую работу по обоснованию убийства Write-Output , и вы готовы помочь мне скрыть преступление.Но я не хотел говорить: «Не делай этого!» и не объяснить некоторые альтернативы. Ниже я приведу некоторые из моих личных лучших практик.

    Создание и возврат объектов

    Вот как вы обычно видите объект, созданный и возвращенный в цикле:

    # Старый способ

    $Processes = Get-Process

    $Results = foreach ($Process in $Processes) {

    $ Результат = [pscustomobject] @ {

    ProcessName = $ process.name

    Дата = Дата

    Дата = Дата

    }

    50002}

    50017

    }

    Вот как я приблизился:

    $Processes = Get-Process

    $Results = foreach ($Process in $Processes) {

        [PSCustomObject]@{

            ProcessName = $Process.Имя

           Дата        = Get-Date

        }

    }

    Я даже не заморачиваюсь с назначением. Одна рекомендация, которую я часто вижу, заключается в следующем:

    $Processes = Get-Process

    $Results = foreach ($Process in $Processes) {

        $Output = [PSCustomObject]@{

            ProcessName = $Process. Name

            Date        = Get-Date

        }

        $Output

    }

    Если вы действительно хотите пометить выходные данные, вы можете использовать одно и то же имя переменной в каждом экземпляре.Я лично считаю это расточительным и все еще дает «ложное чувство безопасности».

    Я настоятельно рекомендую не делать этого:

    # Не делайте этого

    $Processes = Get-Process

    $Results = foreach ($Process in $Processes) {

        # Yield

        [ {

            ProcessName = $Process.Name

            Date        = Get-Date

        }

    }

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

    Вывод текста

    Как упоминалось ранее, вы должны использовать Write-Host только в консольных приложениях в функциях Show-.Но иногда вам все же нужен текст на экране. Хорошим примером этого являются сборки psake на AppVeyor. Write-Output часто рекомендуется вместо Write-Host , потому что он позволяет смешивать строки и форматированные объекты, не сталкиваясь с условиями гонки, возникающими из-за дилеммы конвейера и консоли.

    Старый способ:

    # Старый способ

    Запись-вывод “Процессы PowerShell:”

    Get-Process -Name PowerShell

    Мой способ:

    # Сделайте это

    “Процессы PowerShell1:” 900Process1:”

    -Name PowerShell

    Просто поместите строку отдельно.Это очень удобно для таких вещей:

    $ProcessNames = ‘PowerShell’, ‘mmc’

    foreach ($ProcessName in $ProcessNames) {

        “{0} Processes:” -f $ProcessName

        Get -Process -Name PowerShell

        ‘ ‘

    }

    Я могу просто выполнить операцию форматирования в той же строке, которую я отправляю в выходной поток, без необходимости заключать ее в круглые скобки или использовать подвыражения (в случае, когда Мне нужно свойство объекта в строке).

    Вы можете сделать то же самое со строками здесь для больших блоков текста:

    @’

    Это большой блок текста.

    Много линий.

    Это намного легче читать.

    Вот мои запущенные процессы:

    ‘@

    Get-Process

    Он гибкий и выполняет все те же задачи, что и Write-Output для операций вывода текста на экран.

    Замена –NoEnumerate

    Одной из функций Write-Output является параметр –NoEnumerate .Это позволяет передавать массив как отдельный объект вместо обработки каждого элемента массива как отдельного объекта.

    # Пример использования

    $Array = @(1, 2, 3)

    ‘Обычный: ‘

    Запись-вывод $Array | Объект измерения | Select-Object -ExpandProperty Count

    ‘NoEnumerate: ‘

    Write-Output $Array -NoEnumerate | Объект измерения | Select-Object -ExpandProperty Count

    Результат:

    Вы можете видеть, что –NoEnumerate заставляет массив из трех элементов отображаться как один объект вместо трех.

    Это может быть выполнено оператором унарной запятой:

    # Сделайте это

    $Array = @(1, 2, 3)

    ‘Нормальный:’

    $Array | Объект измерения | Select-Object -ExpandProperty Count

    ‘Унарная запятая:’

    ,$Array | Объект измерения | Select-Object -ExpandProperty Count

    Результаты:


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

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

    RIP In Peace, Запись-Вывод .
    F

    Присоединяйтесь к обсуждению в /r/PowerShell!

    Эхо-эквивалентная команда PowerShell — Write-Output

    Псевдоним эхо-команды PowerShell — запись-вывод. Команда echo используется для вывода строк или переменных на консоль.

    Вы можете использовать эхо-команду PowerShell, как указано:

     echo "Эхо-эквивалент в PowerShell!" 

    Вывод вышеуказанной команды echo в PowerShell:

    Эхо-команда PowerShell Команда echo

    печатает строку или текст, переданный в качестве аргумента.

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

    В этой статье мы обсудим использование команды PowerShell echo и ее эквивалентного псевдонима echo в PowerShell.

    Давайте потренируемся!

    Использование эхо-команды PowerShell

    Синтаксис для использования эха PowerShell:

      эхо [аргумент]
      

    Например,

      echo "Все, что вы должны знать о PowerShell echo"
      

    echo в PowerShell печатает строку или текст, заключенный в двойные кавычки.

    Полезный совет: Как объединить строку в PowerShell!

    Использование эхо-переменной PowerShell

    Вы можете распечатать содержимое переменной с помощью эха.

    Например,

      $strMsg = "Полное руководство по эхо-переменной PowerShell!"
    
    эхо "$strMsg"
    
      

    В приведенном выше примере эхо-переменной печати PowerShell $strMsg содержит значение строкового типа данных.

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

    Вывод вышеуказанной команды:

    Эхо-переменная PowerShell

    Полезный совет: Если вы используете переменную в одинарных кавычках, она печатает имя переменной.Поэтому всегда используйте двойные кавычки.

    Давайте попрактикуемся в эквивалентной команде эха PowerShell!

    Полезный совет: Как выйти из скрипта в PowerShell!

    Использование Write-Output в качестве эхо-эквивалента PowerShell

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

    Синтаксис для использования команды Write-Output

      Запись-вывод [-InputObject] [-NoEnumerate] []  
    Эхо-эквивалент PowerShell Write-Output

    Давайте потренируемся на примере.

     Write-Output «Эхо-эквивалентная команда PowerShell — Write-Output!» 

    Вывод вышеуказанной команды:

    .
      Эхо-эквивалентная команда PowerShell — Write-Output!  

    Полезный совет: Как удалить пользователя из группы в PowerShell!

    Использование Write-Host для печати содержимого

    Команда Write-Host в PowerShell используется для печати содержимого в консоли PowerShell.

    Вы можете использовать настройку в Write-Host, например, применить цвет переднего плана, цвет фона, цвет шрифта для параметра в команде.

     Write-Host "Эхо-эквивалентная команда PowerShell: Write-Host" -ForegroundColor зеленый -BackgroundColor черный 

    В приведенном выше примере

    Команда Write-Host применяет настройки, такие как цвет переднего плана и цвет фона, к параметрам и печатает их на консоли PowerShell.

    Эхо-эквивалент PowerShell Write-Host

    Полезный совет: Как использовать $null в PowerShell!

    Использование эхо-команды PowerShell в функции

    Вы можете использовать функцию PowerShell echo или Write-Output для печати содержимого переменной.

    Давайте потренируемся на примере.

    Создайте функцию для проверки числа на четное или нечетное. Если число четное, выведите сообщение на консоль, используя Write-Output.

    Если число нечетное, используйте эхо PowerShell для печати сообщения.

     Функция CheckNumberIsEven($num) {
    
        если ($ число% 2 -eq 0) {
            Запись-вывод "$ num четно"
            }
         еще{
            echo "$num нечетное"
         }
    
    }
    
    Чекнумберисевен(4) 

    Эхо-команда PowerShell и команда Write-Output в PowerShell выведут значение в консоль PowerShell.

    Полезный совет: Как оставить консоль PowerShell открытой с помощью переключателя PowerShell NoExit!

    Заключение

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

    PowerShell выводит переданный ей аргумент на консоли.

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

    Write-Output — это псевдоним эха PowerShell для записи выходного сообщения в консоль PowerShell.

    Дельный совет: Использование флагов Active Directory UserAccountControl в PowerShell!

    Write-Host также используется для записи выходного сообщения в консоль PowerShell.

    Он обеспечивает настройку выходных сообщений, например, вы можете изменить цвет шрифта, цвет переднего плана или цвет фона.

    Дополнительные темы о командах PowerShell Active Directory и основах PowerShell можно найти на домашней странице ShellGeek.

    Отбрасывание вывода – powershell.one

    Когда вы пишете сценариев PowerShell , вы обычно хотите контролировать информацию, отправляемую обратно пользователю. Поэтому, когда ваш сценарий использует команды, вы не обязательно хотите, чтобы эти команды передавали свои выходные данные непосредственно пользователю.

    Понимание потоков

    В идеальном мире контролировать и отбрасывать выходные данные команд просто, потому что команды обычно используют потоки PowerShell для передачи информации, и вы можете перенаправлять потоки и назначать их переменным или $null .

    Подавление выходного потока

    Например, если все, что вам нужно, это создать новую папку, вы можете направить поток вывода на $null и отбросить информацию, отправленную обратно New-Item :

      # создать новую папку и удалить возвращенную информацию
    $null = New-Item -Path 'c:\newfolder' -ItemType Каталог
      

    Отображение или скрытие потоков

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

      Get-Variable -Name *preference -Exclude *confirm*,*whatif*,*progress*
      

    Просто установите для потока значение Continue , чтобы сделать его видимым, и значение SilentlyContinue , чтобы скрыть его:

      Имя Значение
    ---- -----
    DebugPreference SilentlyContinue
    ErrorActionPreference Продолжить
    ИнформацияПредпочтения МолчаПродолжить
    VerbosePreference ТихоПродолжить
    ПредупреждениеПредпочтения Продолжить
      

    Каждый поток соответствует Write -командлетам и номеру потока:

    Поток Командлет Идентификатор
    Отладка Запись-Отладка 5
    Ошибка Ошибка записи 2
    Информация Запись информации 6
    Подробный Подробная запись 4
    Предупреждение Предупреждение о записи 3
    Выход Запись-вывод 1
    Хост Хост записи 6

    Существует два потока, которые , а не управляются переменными предпочтений и всегда видны: Выход и Хост .

    Поток Output — это поток, который передается нижестоящим командлетам и назначается переменным. Поток Host имеет общий идентификатор потока 6 с потоком Information , и его можно отключить, перенаправив поток 6.

    Перенаправление потоков

    По умолчанию переменным назначается только поток Output . Все остальные потоки либо выводятся непосредственно на консоль, либо скрыты (контролируются вашими предпочтениями).

    Чтобы включить информацию из других потоков в свои переменные, используйте перенаправление: возьмите идентификатор потока, чтобы перенаправить поток в выходной поток ( &1 ).

    Эта строка перенаправляет ошибки и предупреждения в выходной поток и присваивает их переменной:

      # включить ошибки и предупреждения в переменные результаты:
    $all = Get-Process -FileVersionInfo 2>&1 3>&1
      

    После запуска $all содержит результаты, а также все ошибки и предупреждения.

    Особый случай: узел записи

    Write-Host не играл по правилам и обходил потоковую систему вплоть до PowerShell 5 (спасибо Джастину за указание). С тех пор Write-Host совместно использует поток Information , и это важно знать. Поэтому можно снова использовать Write-Host :

    .
    • Write-Host : используйте этот командлет для сообщений, которые пользователь всегда должен видеть. Несмотря на то, что Write-Host использует поток Information , на него не влияет какая-либо переменная предпочтения, такая как $InformationPreference , и всегда установлено значение Continue .
    • Write-Information : используйте этот командлет для сообщений, которые пользователь не должен видеть по умолчанию ( $InformationPreference по умолчанию равен SilentlyContinue ), но которые пользователь может включить.

    Вот доказательство концепции, иллюстрирующее, как вы можете скрыть сообщения, отправленные Write-Host :

      & {
    Запись-предупреждение «Предупреждение»
    «Обычный вывод»
    Пишите-Host "Это исчезнет!"
    } 6>$нуль
      

    При перенаправлении потока 6 на ноль все выходные данные от Write-Host и Write-Information отбрасываются.Вы можете добавить 6>$null к любой команде или вызову скрипта.

    При этом есть два способа отбрасывания потоков:

      # два способа отбрасывания потоков:
    Write-Warning "Предупреждение" 3>$null
    $null = Предупреждение о записи "Предупреждение" 3>&1
      

    Первая строка перенаправляет на $null , что на самом деле то же самое, что и перенаправление на пустую строку, потому что оператор перенаправления принимает только строки, поэтому $null преобразуется в строку:

      Запись-Предупреждение "Предупреждение" 3>''
      

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

    Напротив, вторая строка перенаправляет поток в поток вывода (id #1), поэтому поток объединяется с выводом и может быть назначен переменным, включая специальную переменную $null .

    Это принципиально другой подход. Первая строка позволяет вам выборочно отбрасывать потоков, которые вы хотите скрыть. Вторая строка позволяет вам назначать или отбрасывать всю смесь выходного потока и любого другого потока, который вы объединили в выходной поток.

    Почему некоторые команды некрасивые

    Время от времени вы можете наткнуться на команды, которые не работают по правилам, и написать вывод, который просто не может быть подавлен .

    Например, Get-WindowsUpdateLog — это команда в Windows 10 , которая извлекает информацию об обновлении из файлов .etl и создает для вас файл журнала:

    Когда вы запускаете эту команду, она выдает массу информации, и, похоже, нет способа скрыть или удалить эту информацию:

      # перенаправление потоков не подавляет вывод
    $null = Get-WindowsUpdateLog *>&1
      

    Даже если вы перенаправите все потоков (включая поток 6) в выходной поток и отправите все на $null , сообщения все равно будут отображаться в консоли.

    Запись напрямую на хост

    Эта проблема возникает всякий раз, когда команды записывают напрямую в консоль и обходят механизм потока. Вот строка кода, иллюстрирующая проблему:

      # нельзя заглушить:
    & { [Консоль]::WriteLine("Привет") } *>$null
      

    Заглушение всех выходных данных

    Чтобы отключить прямой вывод консоли и отменить все выходные данные , можно временно отключить внутреннюю команду PowerShell Out-Default .Эта команда используется для записи непосредственно в консоль.

    Узнайте больше о Out-Default , если хотите.

    Хотя вы действительно не можете отключить команду (она жестко закодирована в PowerShell ), вы можете заменить ее своими собственными функциями, фактически перезаписав ее. Итак, вот пример кода, который запускает Get-WindowsUpdateLog без отображения всех сообщений о состоянии:

      # временно перезаписать Out-Default
    функция Out-Default {}
    
    # запустите свой код (гарантировано отсутствие вывода)
    Get-виндовсупдателог
    
    # проверить любую другую прямую консольную запись
    [Консоль]::WriteLine("Привет")
    
    # восстановить значение по умолчанию
    Функция Remove-Item -Path: Out-Default
      

    Пока Out-Default заменяется вашей собственной пустой функцией, PowerShell не выдает никакого вывода вообще . Это относится как к сценариям, так и к интерактивным командам, которые вы можете вызывать. Поэтому убедитесь, что вы удалили свою функцию Out-Default , как только вы будете готовы снова увидеть вывод.

    Этот трюк Out-Default не так уж и бесполезен, как вы думаете. Когда вы просматриваете группы пользователей, вы обнаружите множество тем, посвященных этой проблеме.

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

    Теперь вы знаете: это немного перебор. Просто затените Out-Default до тех пор, пока вы хотите отключить PowerShell .

    мыслей о том, когда использовать — Write-Host, Write-Output, Write-Debug, Write-Warning, Write-Verbose и Write-Error/Throw — SQL Jana

    PowerShell стал предпочтительным средством автоматизации на платформе Microsoft, будь то Windows или Azure. Однако в отношении некоторых вещей нет официальных руководств по передовым методам и стандартам. Иногда блоггеры делают что-то неправильно в своих примерах, тем самым подкрепляя плохие практики. Надеюсь, этот небольшой пост поможет вам соединить некоторые точки! Пожалуйста, прокомментируйте, если я утверждаю что-то, что не является общепринятой передовой практикой. В частности, мы рассмотрим следующие командлеты

    .
    • Хост записи
    • Запись-вывод
    • Запись-Отладка
    • Предупреждение о записи
    • Ошибка записи/сброс
    • Подробная запись
    • Ход записи

    Перво-наперво — CmdletBinding:

    Допустим, у вас есть простая функция

    функция Get-Sum($a, $b)
    {
        $а + $б
    }
     

    Эта функция (плохой пример для подражания) имеет два параметра «a» и «b» и добавляет их.Когда вы запускаете это, подсказки выглядят следующим образом:

    Как мы и ожидали. Однако что, если нам нужны другие параметры, подобные приведенным ниже, которые вы видите как часть встроенных командлетов?

    На самом деле оказывается, что добавить эту поддержку в свою функцию довольно просто, просто добавив в нее декоратор CmdletBinding, как показано ниже

    функция Get-Sum
    {
       [Привязка командлета()]
        параметр (
            [инт] $а,
            [целое] $b
        )
    
        $а + $б
    }
     

    Обратите внимание на небольшие изменения, которые мы внесли

    • Мы добавили [CmdletBinding()]
    • Определен блок параметров с типами данных для наших параметров

    Теперь, если мы попытаемся запустить нашу функцию Get-Sum, расширенные параметры функции волшебным образом появятся в нашей собственной функции!

    Давайте изменим нашу функцию, добавив оператор Write-Verbose

    функция Get-Sum
    {
       [Привязка командлета()]
        параметр (
            [инт] $а,
            [целое] $b
        )
    
        Write-Verbose ("О добавлении [{0}] и [{1}]" -f $a, $b)
        $а + $б
    }
     

    Теперь, когда я запускаю функцию с переключателем «-verbose» в дополнение к двум параметрам, я также получаю «подробный» вывод.

    PS C:\Windows\system32> Get-Sum -a 1 -b 2 -Подробный
    VERBOSE: о добавлении [1] и [2]
    3
     

    Когда я запускаю его без переключателя «-verbose», я получаю только вывод

    PS C:\Windows\system32> Get-Sum -a 1 -b
    3
     

    Это очень типично для PowerShell, где вы иногда запускаете переключатель «-verbose», когда хотите устранить неполадки, и не используете его, когда используете его изо дня в день. Остальные переключатели/параметры, которые вы видите на картинке, также аналогичны.Вы используете их «по мере необходимости».

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

    Хост записи

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

    Основное использование

    Write-Host "Этот текст будет отображаться на консоли!"
     

    отобразит текст на консоли.

    Цветное письмо!

    Write-Host "Это желтый текст на красном фоне!" -BackgroundColor красный -ForegroundColor желтый
     

    Ниже приведен вывод:
    Это желтый текст на красном фоне!

    Запись на той же строке (без новой строки)

    [число] $i = 0
    foreach($i в @(1..100)){
        Хост записи '.' -NoNewline
    }
    
     

    Ниже приведен вывод

     ................................................................ ................................................. 

    Примечание : Если вы хотите отобразить информацию о прогрессе, используйте вместо этого Write-Progress!

    Запись-вывод

    Этот командлет используется для записи выходных данных в конвейер. Если это часть конвейера, выходные данные передаются принимающей команде. Записанные таким образом значения могут быть захвачены в переменную.Он записывается в консоль, если он не передается по конвейеру или не назначается переменной. Это также то же самое, что просто указать что-то вроде переменной или константы (делает ее возвращаемым значением) в отдельной строке вашего кода без какого-либо присвоения. Вывод, записанный таким образом, можно отбросить, передав его в Out-Null. Давайте посмотрим несколько примеров:

    Проходной трубопровод

    Запись-вывод «Мое возвращаемое значение» | Вне сетки

    GridView отображает «Мое возвращаемое значение»

    Присвоение переменной

    $myString = Write-Output "Мое возвращаемое значение"
    $myString
     

    Консоль отображает «Мое возвращаемое значение»

    Запись вывода без использования командлета Write-Output

    #Использование: Get-Sum -a 9 -b 5
    #
    функция Get-Sum($a, $b)
    {
       $а + $б
    }
     

    Использование:

    Get-Sum -a 9 -b 5
    14
     

    В приведенной выше функции «$a + $b» равнозначно «Запись-вывод ($a + $b)». Вывод записывается в конвейер в любом случае. Вы также можете использовать синтаксис « Return $value», чтобы явно указать, что вы возвращаете значение и выходите из текущей области. При использовании двух других методов выполнение будет продолжено и, возможно, будет выведено больше значений (по задумке). В этом аспекте PowerShell отличается от других языков, функции которых обычно имеют одно возвращаемое значение (простой или сложный тип данных).

    Возвращает значения «неповрежденными»

    Иногда сложные типы данных искажаются PowerShell после вывода.Они превращаются в более простые типы данных на один уровень ниже в иерархии объектов. Например, когда возвращается .NET DataTable, он может превратить его в массив объектов .NET DataRow, который является непосредственным дочерним типом в иерархии объектов DataTable. Чтобы этого не произошло, просто поставьте перед строкой возврата «запятую». Это предотвратит распаковку/интерпретацию вашего вывода PowerShell.

    функция Get-DataTable()
    {
       #Некоторая логика...за которой следует возвращаемое значение
    
       #Префикс запятой будет записан в конвейер с неповрежденным значением!
       ,$myDataTable
    }
     

    Out-Null

    Этот командлет позволяет отбросить любые выходные данные, как если бы эти выходные данные никогда не выполнялись.Он не только подавляет выходные сообщения консоли, но и отбрасывает фактические выходные данные, возвращаемые в конвейер другими командами. Это удобно, если вы написали все свои скрипты с большим количеством вывода на консоль и для конкретной нужды, вы не хотите загромождать экран (или) вам не нужно возвращаемое значение, которое производит функция.

    Write-Output "Отправить текст в консоль?" |
        Out-Null
     

    Запись-Отладка

    Если вы работаете с переключателем «-Debug», управление прервется на строке кода, в которой есть «Write-Debug», что позволит вам выполнить код с этого оператора вперед.Это довольно крутая функция, если подумать. Как правило, вы запускаете код без переключателя Debug. Однако придет время, когда вы захотите выйти из своих основных циклов, где у вас есть самая важная логика, и пройти код без необходимости копаться во всем коде. Разбавьте свой код парой операторов «Запись-Отладка» для каждой функции, где, по вашему мнению, вам может понадобиться начать изучение значений переменных и начать пошаговое выполнение отдельных операторов.

    Предупреждение о записи

    Write-Warning имеет цветовую кодировку, привлекающую внимание пользователя.Используйте это, когда вы хотите, чтобы пользователь знал, что что-то не так, но код все равно должен продолжаться, поскольку это не является достаточно большой проблемой, чтобы остановить выполнение. Например, когда вы хотите скопировать файлы в новое место, а файлы уже существуют в этом целевом местоположении. Если бизнес-процесс позволяет перезаписывать цель, все же может быть хорошей идеей сообщить пользователю, что вы перезаписываете, с помощью сообщений типа «Write-Warning».

    Ошибка записи/сброс

    Write-Error следует использовать для не завершающих ошибок — это означает, что выполнение будет продолжаться после строки Write-Error после записи ошибки в поток ошибок.Write-Error имеет множество параметров, которые позволяют настраивать его. Ключевым среди них является параметр «Категория». Хотя раньше он сигнализировал о незавершающих ошибках, на самом деле вы можете остановить выполнение, установив для среды $ErrorActionPreference.

      $ErrorActionPreference = "Стоп";  

    Например, вы можете написать непрерывающую ошибку, как показано ниже

    Ошибка записи "Невозможно подключиться к серверу". -Категория Ошибка подключения
     

    Ошибка записи по сравнению сБросить

    Используйте Throw, если вы хотите остановить выполнение программы (если только не было try/catch для обработки ошибки и возобновления работы с нее).

    PS C:\Windows\system32> кинуть
    ScriptHalted
    В строке:1 символ:1
    + бросить
    + ~~~~~
        + CategoryInfo: OperationStopped: (:) [], RuntimeException
        + FullyQualifiedErrorId: ScriptHalted
    
    PS C:\Windows\system32> бросает "Сервер не найден.  Невозможно продолжить"
    Сервер не найден. Невозможно продолжить
    В строке:1 символ:1
    +выбросить "Сервер не найден.Невозможно продолжить"
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo: OperationStopped: (Сервер не найден. Невозможно продолжить: строка) [], RuntimeException
        + FullyQualifiedErrorId: сервер не найден. Невозможно продолжить
     

    , когда Throw используется внутри функции и если в цепочке вызовов нет блоков try/catch, выполнение останавливается, а консоль отображает ошибку «thrown».

    Подробная запись

    Это наиболее часто используемый из всех обсуждаемых.По сути, это вся дополнительная информация, которую вы хотите видеть во время работы вашей программы, если она была запущена с ключом «-Verbose». Обычно код запускается без этого переключателя. Обычно я использую для каждого шага внутри функции. В дополнение к тому, что я получаю представление о том, над чем ведется работа, если происходит ошибка, я также получаю сообщение о неудачном шаге (даже если он не запущен с ключом -Verbose)!

    Пожалуйста, взгляните на функции в моем предыдущем посте ниже, чтобы увидеть, как Write-Verbose используется в сочетании с обработкой ошибок (с использованием $stepName).

    PowerShell – Working With SQL Server Reporting Services (SSRS) – Get/Set Data Sources & Deploy Reports

    Ход записи

    Я вижу в Интернете вопросы, в которых спрашивают, как отобразить поток точек или что-то в этом роде, если обработка выполняется. Лучший способ передать этот аспект — использовать Write-Progress вместо любого из вышеперечисленных методов.

    Ход выполнения вложенного цикла

    Write-Progress может даже выполнять вложенный цикл.т. е., если в циклах имеется три уровня вложенности, для каждого уровня вложенности может быть выполнено три отображения прогресса.

    $outerLoopMax = 255
    $innerLoopMax = 126
    
    for ($outerCounter=1; $outerCounter -lt $outerLoopMax; $outerCounter++) {
      Write-Progress -Activity "Прогресс основного цикла:" `
                       -PercentComplete ([int](100 * $outerCounter / $outerLoopMax)) `
                       -CurrentOperation("Completed {0}%" -f ([int](100 * $outerCounter / $outerLoopMax))) `
                       -Status ("Внешний цикл работает с элементом [{0}]" -f $outerCounter) `
                       -Идентификатор 1
    
        Старт-Сон - Миллисекунды 100
    
        for ($innerCounter=1; $innerCounter -lt $innerLoopMax; $innerCounter++) {
          Write-Progress -Activity "Прогресс внутреннего цикла:" `
                           -PercentComplete ([int](100 * $innerCounter / $innerLoopMax)) `
                           -CurrentOperation("Completed {0}%" -f ([int](100 * $innerCounter / $innerLoopMax))) `
                           -Status ("Внутренний цикл работает над элементом [{0}]" -f $innerCounter) `
                           -Идентификатор 2 `
                           -родительский идентификатор 1
    
            Старт-сна-миллисекунд 10
        }
    }
     

    Обратите внимание, что для такого вложенного прогресса задайте разные значения Id для родительского и дочернего Write-Progress, а в дочернем Write-Progress установите для параметра ParentId значение Id родителя.

    Вывод:

    Хотя это очень короткое сообщение, мы надеемся, что оно подчеркивает контекст, в котором обычно используются команды, связанные с «Записью». Если есть один вывод из этого поста, вам следует часто использовать Write-Verbose! Идеальный сценарий/функция PowerShell использует все вышеперечисленное в правильном сочетании для наилучшего взаимодействия с пользователем/разработчиком.

    Нравится:

    Нравится Загрузка…

    Родственные

    Какая запись подходит для PowerShell?

    Если и есть один командлет, который больше всего сбивает с толку новичков в PowerShell, то это Write-Host.Новички видят такие команды, как Write-Output, Write-Host и, если работает PowerShell 5.0 Write-Information. Определить, какой из них использовать, может быть немного сложно. Итак, позвольте мне упростить: пока вы можете игнорировать Write-Information. Если у вас есть немного больше опыта, вы можете найти вводную статью здесь.

    Вместо этого давайте сосредоточимся на Write-Output, который имеет псевдонимы write и echo и Write-Host: в чем разница? Чтобы ответить на этот вопрос, нам сначала нужно сделать шаг назад и посмотреть, как работает PowerShell.Думайте о PowerShell как о движке, который вы можете установить на разные транспортные средства. Эти транспортные средства называются приложениями для хостинга. По умолчанию Microsoft позволяет запускать PowerShell внутри консольного приложения (cmd.exe) и PowerShell ISE. Но другие приложения также могут размещать PowerShell. Несколько лет назад такие инструменты, как PowerGUI и PowerShell Plus, были популярны и также содержали механизм PowerShell. Коммерческие продукты, такие как PowerShell Studio от SAPIEN Technologies, также поддерживают PowerShell.И хотя существуют рекомендации о том, как приложения должны размещать PowerShell, могут быть небольшие различия в реализации, которые могут означать для вас разные впечатления.

    В конечном счете, выбор варианта письма зависит от вашего выбора места назначения. Другими словами, где находится командлет , записывающий ? У вас есть два варианта: конвейер или хост. Есть вполне веские причины писать в любой из пунктов назначения, но вам нужно понять, почему. Вот пример функции PowerShell, написанной кем-то, кто только начинает.Это не чей-то настоящий сценарий, а то, что я написал на основе того, что видел.

     Функция Get-StoppedService {
    
    Param([string]$имя_компьютера = $env:имя_компьютера)
    
    $s = Get-Service -имя_компьютера $имя_компьютера
    $остановлено = $s | где {$_.Status -eq 'Остановлено'}
    foreach ($ сервис в $ остановлен) {
        Служба записи хоста $
     }
    }
     

    Пользователь запускает функцию, и, насколько ему известно, она работает и удовлетворяет его потребности.

    Рекламный контент

    Диспетчер удаленных рабочих столов Devolutions

    Devolutions RDM централизует все удаленные подключения на единой платформе, которая безопасно используется пользователями и всей командой. С поддержкой сотен интегрированных технологий, включая несколько протоколов и VPN, а также со встроенными инструментами управления паролями корпоративного уровня, глобальным и детальным контролем доступа и надежными мобильными приложениями, дополняющими настольные клиенты.

    Узнать больше

    Использование Write-Host (Изображение предоставлено Джеффом Хиксом)

    Но так ли это на самом деле? Позже они пытаются использовать эту функцию в такой команде:

     get-stoppedservice -Computername chi-p50 | выходной файл c:\work\services.текст
     

    Но когда они смотрят файл, в нем ничего нет. Это произошло из-за того, что Write-Host написал в хост-приложение, в данном случае в консоль. Если это поможет, подумайте об этом как о записи на экран. Но ничего не было записано в конвейер PowerShell. Если это произойдет, то последующим командам, таким как Out-File, нечего будет делать. Рекомендуемый метод — использовать Write-Output.
     Функция Get-StoppedService {
    
    Param([string]$имя_компьютера = $env:имя_компьютера)
    
    $s = Get-Service -имя_компьютера $имя_компьютера
    $остановлено = $s | где {$_.Статус -eq «Остановлено»}
    foreach ($ сервис в $ остановлен) {
        Запись-вывод $service
     }
    }
     

    Разница драматична. Использование Write-Output (Изображение предоставлено: Jeff Hicks)

    Вместо того, чтобы выводить текст на экран, мы теперь записываем объект в конвейер. Система форматирования PowerShell обрабатывает представление объекта на экране, чтобы вы могли его прочитать. И теперь команда Out-File также будет работать, потому что объекты записываются в конвейер.

    Прежде чем мы зайдем слишком далеко, позвольте мне отметить, что эта итерация также указывает на «текстовое» мышление.Вам не нужно вручную перечислять и записывать каждый результат в конвейер, как вы могли бы сделать в VBScript. Вместо этого позвольте PowerShell справиться с этим.

     Функция Get-StoppedService {
    
    Param([string]$имя_компьютера = $env:имя_компьютера)
    
    $s = Get-Service -имя_компьютера $имя_компьютера
    $остановлено = $s | где {$_.Status -eq 'Остановлено'}
    Запись-вывод $Stopped
    
    }
     

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

    Вывод должен заключаться в том, чтобы всегда записывать в конвейер. Write-Host не приносит вам никакой пользы и, по мнению некоторых в сообществе PowerShell, является большим грехом.

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

    Вот переработанная версия простой функции:

     Функция Get-StoppedService {
    
    Param([string]$имя_компьютера = $env:имя_компьютера)
    
    Write-Host "Получение услуг с $computername" -ForegroundColor Cyan
    $s = Get-Service -имя_компьютера $имя_компьютера
    
    Write-Host "Обнаружено всего $($s.count) сервисов" -ForegroundColor Green
    $остановлено = $s | где {$_.Status -eq 'Остановлено'}
    
    Write-Host "Обнаружено всего $($stopped.count) остановленных служб" -ForegroundColor Green
    $Остановлено
    
    }
     

    Сообщения Write-Host будут чередоваться с выводом функции.Или, если вы сохраните конвейерные результаты в переменную, вы все равно сможете видеть сообщения Write-Host. Интеграция Write-Host (Изображение предоставлено Джеффом Хиксом)

    Помните, что нет никакого способа сохранить какие-либо выходные данные Write-Host, если только вы не используете расшифровку PowerShell. И, конечно же, поскольку это текстовый файл, в нем не будет никакого цвета. Поэтому вы можете подумать: «Круто. Я буду использовать цвета с Write-Host и не буду об этом беспокоиться».

    Как следует из названия, Write-Host выполняет запись в хост-приложение.В случае с консолью и PowerShell ISE моя функция будет работать как положено. Но нет никакой гарантии, что другие размещенные приложения будут учитывать параметр foreground,color. У вас может не быть возможности предвидеть, какой хост кто-то может использовать для запуска вашей команды. По этой причине я бы не советовал вам слишком полагаться на Write-Host. Есть лучшие способы предоставления обратной связи, такие как подробные операторы или командлет Write-Progress.

    И прежде чем кто-нибудь окликнет меня: да, я написал несколько инструментов PowerShell, которые явно используют преимущества цветовых функций Write-Host.Но я делаю это, зная, что все, что я могу сделать, это просмотреть информацию на экране и что мне нужно использовать консоль или ISE. Я также создавал инструменты и сценарии PowerShell в течение 10 лет, поэтому я понимаю, как обойти правила и последствия.

    Если вы только начинаете, научитесь записывать объекты в конвейер. Если вы не чувствуете необходимости набирать «Write-Output», вы никогда не запутаетесь. Пусть PowerShell сделает всю работу.

    Форматирование вывода · Справочник Powerstart to Powershell

    Цветовое форматирование

    Добавление цвета к выходным данным

      write-host -BackgroundColor DarkYellow -ForegroundColor Черный "Шмель"
      

    Версия с короткой стрелкой

      write-host -b DarkYellow -f Черный "Шмель"
      

    Форматирование строки

    Запись переменной традиционным способом

      $users = @('Боб','Алиса','Сьюзан')
    write-host "Привет от $users[0] до $users[1]"
      

    Запись переменной с форматированием и escape-символами

      $users = @('Боб','Алиса','Сьюзан')
    write-host ("Привет от {0} до {1} " -f $users[0],$users[1])
    write-host ("Привет от {1} до {0} " -f $users[0],$users[1])
    write-host ("Привет от {0,15} до {1,15}" -f $users[0],$users[1])
    write-host ("Привет от {0} `n`t до {1} " -f $users[0],$users[1])
      

    Запись переменной с форматированием

      функция PrettyPrint-Array {
        параметр(
                [строка[]]$массив = @()
        )
    
        запись-хост("| {0,15} |" -f "Имена")
        (0. .18) | % { запись-хост -nonewline "#" }
        запись-хост ""
    
        foreach ($ элемент в массиве $) {
            запись-хост ("| {0,15} |" -f $элемент)
        }
    }
    $users = @('Боб','Алиса','Сьюзен')
    PrettyPrint-Array -массив $users
      

    Запись других типов

      запись-хост ("{0,-10} | {1,10}" -f "влево", "вправо")
    
    хост записи ("{0}" -f 3.1456)
    запись-хост ("{0,10}" -f 3.1456)
    
    запись-хост ("{0:D10}" -f 3)
    запись-хост ("{0,15:D10}" -f 3)
    
    
    хост записи ("{0:N10}" -f 3.1456)
    запись-хост("{0,15:N10}" -f 3.1456)
    
    запись-хост ("{0:X}" -f 14)
    хост записи ("{0:C10}" -f 3.1456)
    
    запись-хост ("{0:D}" -f (получить-дату))
    запись-хост ("{0:u}" -f (получить-дату))
    write-host("{0,30:yy MM dd hh mm ss}" -f (get-date))
    запись-хост (получить-дата).ToString ("гг мм дд чч мм сс")
    
    write-host ("мне нужны скобки {{ {0} }}" -f (get-date))
      

    Формат, связанный с сетью Dot.aspx#Format_Custom) Количество Даты Композит

      функция Write-PingPong {
        параметр(
            [инт] $ высота = 20,
            [целое] $ ширина = 60,
            [число] $ слева = 2,
            [инт]$право = 2,
            [число]$ballx = 3,
            [целое]$балли = 5
        )
    
        если ($left -lt 1) { $left = 1}
        если ($left -gt ($height-1)) { $left = $height-1}
    
        если ($право -lt 1) {$право = 1}
        если ($право -gt ($высота-1)) {$право = $высота-1}
    
        [int[]]$lefts = @(($left-1),$left,($left+1))
        [int[]]$rights = @(($right-1),$right,($right+1))
    
    
    
    
        $линии = @()
    
        $ln = ("+{0,$width}+" -f ""). ToCharArray()
        foreach($i in (1..($width-1))) {
            $ln[$i] = "-"
        }
        $lines += ($ln -join "")
    
    
        $ln = ("|{0,$width}|" -f "")
        foreach ($ i в (0.. $ высота)) {
            $l = $ln.ToCharArray()
            если ($i -in $lefts) {
                $l[1] = '#'
            }
            если ($i -в $правах) {
                $l[$width-1] = '#'
            }
            если ($i -in $bally) {
                $l[$ballx] = '*'
            }
            $lines += ($l -соединение "")
        }
    
        $ln = ("+{0,$width}+" -f "").ToCharArray()
        foreach($i в (1..($ ширина-1))) {
            $ln[$i] = "-"
        }
        $lines += ($ln -join "")
        $joined = ($lines -join "`n")
    
        ясно-хозяин
        запись-хост $joined
    }
    
    функция Play-PingPong {
        параметр(
            $диркс = +1,
            $diry = +1,
            $шаг = 1,
            $ высота = 20,
            $ширина = 60,
            $fps = 5,
            $playforstep = 500
        )
        [int]$msмежду кадрами = 1000/$fps
    
        [int]$ballx = ($ширина/2)
        [int]$bally = Get-Random -Минимум 0 -Максимум $height
    
    
        foreach ($ время выполнения в (0. . $ playforstep)) {
            $skew = $(команда измерения {
                $ballx = $ballx + ($dirx*$stepf)
                $bally = $bally + ($diry*$stepf)
    
                если ($ballx -ge ($width-1) -или $ballx -le 1 ) {
                    $диркс = $диркс*-1
                    $ballx = $ballx + ($dirx*$stepf*2)
                }
                если ($bally -ge $height -или $bally -le 0 ) {
                    $diry = $diry*-1
                    $bally = $bally + ($diry*$stepf*2)
                }
    
                написать-пинг-понг -левый $bally -правый $bally -ballx $ballx -bally $bally -высота $высота -ширина $ширина
            }).миллисекунды
    
            если ($skew -lt $msbetweenframes) {
                start-sleep -миллисекунды ($msbetweenframes-$skew)
            }
    
        }
    }
      

    Ввод и вывод PowerShell — Технические мысли

    До этого момента в серии статей «Изучение PowerShell» мы рассматривали примеры с очень простым вводом и выводом PowerShell. Обычно мы статически предоставляем входные данные путем жесткого кодирования переменной (например, $input = ‘SomeInput’ ).До сих пор наши выходные данные в основном состояли из Write-Host . В этом уроке мы постараемся получить более динамичный ввод и покажем вам, как получить больший контроль над вашим выводом.

    Видео

    Если вы предпочитаете формат видео письменной документации, я обсуждаю эту тему в следующем видео TechThoughts:

    Ввод PowerShell

    Часто вашему коду PowerShell необходимо оценивать входные данные определенного типа. Этот ввод может быть статически предоставлен вами заранее.Однако часто бывают случаи использования, когда желательно получить динамический ввод.

    Ввод PowerShell из командлетов

    Конечно, вы можете использовать выходные данные командлетов для ввода вашей функциональности PowerShell. В зависимости от того, что возвращает командлет, вы можете выполнять множество различных функций на основе сгенерированного ввода.

    • запуск командлетов (Get-Process)
      • командлет генерирует выходные данные
        • использование выходных данных в качестве входных данных
          • выполнение функций на основе динамического ввода

            Давайте рассмотрим пример, в котором мы используем PowerShell для получения динамических результатов с веб-сайта.Если вы пришли из более ориентированного на Linux фона, это немного похоже на использование curl .

             # получить динамическое содержимое с веб-сайта
            $webResults = Invoke-WebRequest -Uri 'https://reddit.com/r/powershell.json'
            $rawJSON = $webResults.Content
            $objData = $rawJSON | ConvertFrom-Json
            $posts = $objData.data.children. data
            $сообщения | Выберите-Объект Заголовок,Оценка | Оценка объекта сортировки по убыванию
             

            Здесь мы используем Invoke-WebRequest для получения веб-контента из /r/PowerShell.(Кстати, отличный ресурс PowerShell!) HTML не особенно полезен для нас, так как мы хотим работать с объектами в PowerShell. Обратите внимание, что я посетил JSON-версию этой страницы. В результате выходное содержимое этого командлета находится в формате JSON. Поскольку JSON — это структурированные данные, мы можем взять на себя управление и преобразовать их в собственные объекты PowerShell, используя ConvertFrom-JSON .

            Примечание. Существует множество команд convert. Это позволяет вам получать данные из различных источников и продолжать работать с объектами PowerShell!

            В исходном формате объекта очень просто изучить доступные подсвойства.Затем мы можем углубиться в них и найти информацию о сообщениях. Когда у нас есть пост-данные, мы можем выбирать и сортировать входные данные, которые нам нужны. В этом примере возвращаются заголовок сообщения и оценка (голоса).

            Запустите приведенный выше пример на своем компьютере, чтобы увидеть результаты. Попробуйте изучить другие доступные вложенные свойства в $posts .

            Использование выходных данных командлета в качестве входных данных

            Как бы вы использовали выходные данные этого примера в качестве входных данных? Это полностью зависит от вас! Вы можете написать код PowerShell для:

            • Отправить себе по электронной почте 3 самых популярных сообщения PowerShell за день
            • Отправить себе текстовое сообщение с самым популярным сообщением дня
            • Показать 10 лучших сообщений дня при входе в систему

            Вы будете использовать PowerShell, чтобы станьте умнее с PowerShell! Мы расскажем больше о том, как создавать скрипты для PS1, позже в этой серии, так что следите за обновлениями!

            Вы будете использовать PowerShell, чтобы стать умнее с помощью PowerShell!

            Чтение ввода хоста

            Read-Host — это еще один способ получить динамический ввод от вас или ваших пользователей. Снова используя предыдущий пример, мы смогли вернуть только желаемое количество сообщений:

            .
             [int]$numPosts = Read-Host -Prompt "Введите количество сообщений для чтения"
            #получить динамическое содержимое с веб-сайта
            $webResults = Invoke-WebRequest -Uri 'https://reddit.com/r/powershell.json'
            $rawJSON = $webResults.Content
            $objData = $rawJSON | ConvertFrom-Json
            $posts = $objData.data.children.data
            $сообщения | Выбрать-Объект Заголовок, URL | Sort-Object Score - по убыванию | Select-Object -First $numPosts
             

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

            Вот забавный пример, где мы можем получить веб-данные в сочетании с Read-Host для отображения желаемого количества фактов о кошках:

             [int]$numFacts = Read-Host -Prompt "Введите желаемое количество фактов о кошках"
            $webResults = Invoke-RestMethod -Uri "https://catfact. ninja/facts?limit=$numFacts&max_length=140"
            $ веб-результаты.данные
             

            Обратите внимание, что catfact.ninja — это API , а не традиционная веб-страница. В результате подходящим командлетом является Invoke-RestMethod , а не Invoke-WebRequest .

            Получить содержимое

            Другим часто необходимым источником динамического ввода являются файлы на устройстве. На практике вы часто будете просматривать файлы журналов. Давайте посмотрим на пример файла журнала:

             [INFO][Date]Нормальная работа
            [INFO][Date]Нормальная работа
            [INFO][Date]Нормальная работа
            [ОШИБКА][Дата]192.168.1.5 невозможно получить доступ
            [INFO][Date]Нормальная работа
             

            Get-Content может получить содержимое файла для использования в качестве входных данных.

             $logContent = Get-Content C:\Test\SampleLog.log
            
            # получить только те записи, которые имеют IP-адрес, используя регулярное выражение
            $regex = "\b\d{1,3}\. \d{1,3}\.\d{1,3}\.\d{1,3}\b"
            $logContent | Select-String -Pattern $regex -AllMatches
            
            # получить только те записи, у которых есть IP-адрес, используя Where-Object
            $logContent | Где-объект {$_ - как "*.*.*.*"}
             

            Содержимое SampleLog хранится в $logContent .Теперь, когда у вас есть эти входные данные, вы можете приступить к оценке. Может быть критически важно, чтобы PowerShell предпринял какое-либо действие, если IP-адрес обнаружен в журнале. Вы можете анализировать данные с помощью регулярного выражения (regex) или с помощью Where-Object. Если IP-адрес обнаружен, вы можете подать заявку, отправить уведомление или выполнить какое-либо другое действие.

            Вы не ограничены только текстовыми или стандартными файлами журналов. Get-Content может извлекать входные данные из широкого спектра типов файлов. Вот пример, где вы можете получить данные из CSV-файла.Помните, что существует множество командлетов преобразования, поэтому вы можете легко преобразовать данные csv в обычный формат объектов PowerShell!

             $rawCSVInput = Get-Content C:\Test\SampleCSVFile. csv
            $objData = $rawCSVInput | ConvertFrom-CSV
             

            Выходные данные PowerShell

            Если вы хотите отобразить результаты обратно на консоль или создать файл результатов, вам потребуется создать некоторый тип вывода PowerShell. Есть несколько способов сделать это, и один вы должны избегать!

            Хост записи

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

             # Вывод простой строки в консоль
            Write-Host 'Вывод текста на консоль'
            
            # Настройте вывод в консоль с помощью цветов:
            Write-Host "Предупреждение" - ForegroundColor Yellow
            Write-Host "ERROR" - ForegroundColor Red
            Write-Host "Отлично работает" - ForegroundColor Green
            Write-Host "CRITICAL ERROR" -BackgroundColor Red -ForegroundColor White
             

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

             $hostInfo = Get-Host
            Запись хоста $hostInfo
             

            В приведенном выше примере вы получите вывод: System.Management.Automation.Internal.Host.InternalHost

            Это связано с тем, что $hostInfo является объектом PowerShell, а не строкой. Мы можем углубиться в этот объект, пока не получим строку, которую может использовать Write-Host:

            .
             $hostInfo = Get-Host
            Запись хоста $hostInfo
            Запись хоста $hostInfo.Версия
             

            Write-Host прост в реализации, а его цветовые возможности делают его привлекательным выбором для отображения результатов пользователям. Тем не менее, вы не должны использовать его. Это может быть удобно при написании нового PowerShell, чтобы убедиться, что ваш код содержит ожидаемые значения. Кроме того, следует избегать его использования. Джеффри Сновер объясняет причины этого в своем посте Write-Host считается вредным . В нем он выступает за использование Write-Verbose вместо Write-Host. Мы рассмотрим Write-Verbose позже в этой серии, когда начнем создавать функции PowerShell.

            Использование Write-Host почти всегда неправильно.

            Джеффри Сновер — создатель PowerShell

            Запись-вывод

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

            Когда вы запускаете Get-Process и видите результаты в консоли PowerShell, это было выполнено Write-Output.Все эти примеры выполняют одно и то же:

             # Пример 1
            Get-процесс
            
            # Пример 2
            $processes = Получить-Процесс
            Процессы записи-вывода $
            
            # Пример 3
            $processes = Получить-Процесс
            $процессы
             

            В результате вы не часто увидите Write-Output, написанный в коде PowerShell. Это подразумевается как поведение вывода по умолчанию.

            Исходящий файл

            Консоль — не единственный способ вывода PowerShell. Если вы хотите вывести данные в файл, вы можете использовать Out-File . Out-File может отправлять весь вывод в файл. Это означает, что он немного более интеллектуален, чем Write-Host , и может обрабатывать возврат всего объекта из командлета в файл. Ниже приведены некоторые примеры:

             # Пример 1
            $processes = Получить-Процесс
            $ процессы | Out-File - FilePath C:\Test\processInfo.txt
            
            # Пример 2
            Get-процесс | Out-File - FilePath C:\Test\processInfo.txt
             

            Не забывайте об этих командлетах преобразования! Есть несколько выходов! Итак, если ваш файл должен быть в формате CSV, вы можете использовать ConvertTo-CSV :

            .
             $processes = Get-Process
            $ процессы | ConvertTo-Csv -NoTypeInformation | Внешний файл c:\test\processes.