Powershell: Командлет Test-Connection, отображающий нежелательные данные.

Созданный на 28 апр. 2018  ·  64Комментарии  ·  Источник: PowerShell/PowerShell

Действия по воспроизведению

The Test-Connection cmdlet is displaying unwanted data as part of the result.

Code:

Test-Connection www.microsoft.com -Count 1 -Quiet

Ожидаемое поведение

It should display just the word: True

Фактическое поведение

Pinging www.microsoft.com [23.204.153.19] with 32 bytes of data:
Reply from 23.204.153.19: bytes=32 time=17ms TTL=58
Ping complete.
True

Данные окружающей среды

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.1.0-preview.2
PSEdition                      Core
GitCommitId                    v6.1.0-preview.2
OS                             Microsoft Windows 10.0.16299
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Area-Cmdlets-Management Committee-Reviewed Issue-Bug Resolution-Fixed

Самый полезный комментарий

@GeeLaw :

Хорошая находка, но в данном случае для обхода ошибки требуется -InformationAction Ignore .

$InformationActionPreference прежнему по умолчанию SilentlyContinue , и это не должно измениться.

Ошибка в том, что WriteInformation() вызывает ссылку для ошибочного использования тега PSHOST , который эффективно _byppass_ значение $InformationActionPreference а также -InformationAction SilentlyContinue (но, как указано , -InformationAction Ignore _эффективно подавляет вывод).

Сказанные вызовы WriteInformation() фактически делают то, что делает Write-Host , чтобы _unconditional_ отображать свой вывод (по замыслу).

@iSazonov : Я действительно не смотрел на поведение других командлетов с индикаторами выполнения, но с -Quiet я бы _не_ ожидал индикатора выполнения, даже при интерактивном вызове.

Все 64 Комментарий

Это работает правильно в 5.1, но не в 6, поэтому я реклассифицировал проблему как ошибку.

Причина в том, что текущий код вызывает WriteInformation (вслепую?).

См. Строку 751 файла TestConnectionCommand.cs , а также строку 775 и строку 783.

Временный обходной путь для остановки отображения информации на хосте - использовать общий параметр InformationAction . Пример:

Test-Connection www.microsoft.com -Count 1 -Quiet -InformationAction Continue

С точки зрения сценариев это не будет проблемой , поскольку текстовая информация никогда не записывается в конвейер, и нет, текстовый вывод не является частью данных результата, которые определяются как вещи, отправляемые в конвейер. Кроме того, переключатель Quiet определен для возврата более простых результатов ( int или bool вместо объектов записи). Я должен признать, что нельзя было ожидать InformationRecord с Quiet . Однако, зная причину, я говорю, что лучше не связывать InformationAction и Quiet .

В PowerShell 5.1 Test-Connection вообще не вызывает WriteInformation . Кстати, значение по умолчанию для $InformationPreference в PowerShell 5.1 и PowerShell Core 6.0.2 - SilentlyContinue . Автор номера может иметь другую действительную ценность, когда воспроизводит номер. (Возможно, PS 6.1 Core изменил значение по умолчанию на $InformationPreference ? Я не уверен.)

Если бы в PS 6.1 Core для $InformationPreference умолчанию было установлено значение SilentlyContinue , текстовой информации не было бы, если пользователь явно не запросит ее.

Мне нужно больше отзывов.
Проблема в том, что в режиме скрипта и в интерактивном режиме он должен работать по-разному. В интерактивном режиме пользователь, вероятно, предпочтет видеть прогресс (полосу), как это происходит с командой ping.exe. Это относится и к другим параметрам.

@ mklement0 Если у вас будет время, то ваша помощь будет полезна.

@GeeLaw :

Хорошая находка, но в данном случае для обхода ошибки требуется -InformationAction Ignore .

$InformationActionPreference прежнему по умолчанию SilentlyContinue , и это не должно измениться.

Ошибка в том, что WriteInformation() вызывает ссылку для ошибочного использования тега PSHOST , который эффективно _byppass_ значение $InformationActionPreference а также -InformationAction SilentlyContinue (но, как указано , -InformationAction Ignore _эффективно подавляет вывод).

Сказанные вызовы WriteInformation() фактически делают то, что делает Write-Host , чтобы _unconditional_ отображать свой вывод (по замыслу).

@iSazonov : Я действительно не смотрел на поведение других командлетов с индикаторами выполнения, но с -Quiet я бы _не_ ожидал индикатора выполнения, даже при интерактивном вызове.

@ mklement0 Спасибо за ответ и исправление в PSHostTag . Мне кажется, что InformationPreference ( InformationAction ) не примет Ignore ? Это верно в 5.1 и 6.0.2. Возможно в 6.1 изменилось. ( InformationActionPreference - это новый псевдоним для InformationPreference ?)

Кроме того, мой первый комментарий был ошибочным, потому что он устанавливает InformationAction в Continue . Правильный обходной путь - отбросить поток 6 (информационный поток), перенаправив его на $null , т. Е.

Test-Connection www.microsoft.com -Count 1 -Quiet 6> $null

Проверьте правильность следующим образом:

Write-Host 'Hello, world' 6> $null

Он не должен ничего писать хосту.

@GeeLaw :

Мне кажется, что InformationPreference (InformationAction) не принимает Ignore?

Да, _preference variable_ не принимает Ignore , а _common параметр_ принимает.

То есть вы можете подавить информационный поток (номер 6 ) _ для данного вызова_, но не _категорически_ для всей области - по дизайну.

Следовательно, следующие два утверждения эквивалентны:

Test-Connection www.microsoft.com -Count 1 -Quiet 6> $null
Test-Connection www.microsoft.com -Count 1 -Quiet -InformationAction Ignore

Другими словами: и 6> $null и -InformationAction Ignore - эффективные обходные пути.

InformationActionPreference - это новый псевдоним для InformationPreference ?

Нет, имя всегда было $InformationPreference , следуя шаблону $VerbosePreference , $WarningPreference и $DebugPreference .

Насколько я могу судить, это только пара -ErrorAction / $ErrorActionPreference которой имя переменной предпочтения сохраняет часть Action .


В стороне относительно запрета Ignore в качестве значения _предварительных переменных_ действия:

  • Это ограничение связано с фундаментальной проблемой дизайна, потому что автоматически определенные локальные переменные предпочтений используются для распространения значений общих параметров внутри расширенных функций - см. # 1759

  • Ограничение не применяется во время _assignment time_, что означает, что вы не увидите проблемы, пока предпочтение (возможно, неявно) не будет применено в следующий раз - см. # 4348

    • В более общем смысле, в любой области, кроме глобальной, проверка вообще не выполняется; сравните $ErrorActionPreference = 'bogus' с & { $ErrorActionPreference = 'bogus' } - см.

      3483.

@ mklement0 Я спрашивал о псевдониме, потому что вы упомянули его как InformationActionPreference .

Насколько мне известно, -XxxAction-Verbose и -Debug ) просто устанавливает соответствующую переменную предпочтения внутри вызванного командлета. Как описано в разделах справки about_ , в частности, у нас есть следующее:

The value of the -InformationAction parameter, if used, overrides the current value of the $InformationPreference variable.

Within the command or script in which it is used, the InformationAction common parameter overrides the value of the $InformationPreference preference variable, which by default is set to SilentlyContinue.

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

function test-func { [cmdletbinding()]param() process { $InformationPreference } }
test-func # gives SilentlyContinue
test-func -InformationAction Continue # gives Continue
test-func -InformationAction Ignore # gives Ignore

В 5.1 и 6.0.2 InformationAction не принимает Ignore , что можно продемонстрировать в следующем фрагменте:

function test-func { [cmdletbinding()]param() process { write-information 'writing' } }
test-func -InformationAction Ignore

производит

Write-Information : The value Ignore is not supported for an ActionPreference variable. The provided value should be used only as a value for a preference
parameter, and has been replaced by the default value. For more information, see the Help topic, "about_Preference_Variables."
At line:1 char:57
+ ...  { [cmdletbinding()]param() process { Write-Information 'writing' } }
+                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Information], NotSupportedException
    + FullyQualifiedErrorId : System.NotSupportedException,Microsoft.PowerShell.Commands.WriteInformationCommand

Интересно, изменилось ли это в 6.1.


Есть еще одна интересная вещь: $VerbosePreference и $DebugPreference фактически принимают более широкий диапазон, чем тот, который может быть установлен соответствующим общим параметром. Например, можно установить $VerbosePreference в Inquire явным назначением, но это невозможно с помощью -Verbose switch, потому что, в конце концов, это переключатель и отображает $True / $False до Continue / SilentlyContinue .

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

Еще один раунд экспериментов показывает, что следующий код работает:

Write-Information 'writing' -InformationAction Ignore

Но это было бы обременительно для разработчиков, поскольку мы должны защитить Write-Information проверкой $InformationAction -eq 'Ignore' и в первую очередь избегать ее вызова, например,

Function Test-Inf1
{
    [CmdletBinding()] Param ( )
    Process { Write-Information 'Hello, world!' }
}
Function Test-Inf2
{
    [CmdletBinding()] Param ( )
    Process { If ($InformationPreference -ne 'Ignore') { Write-Information 'Hello, world!' } }
}
Test-Inf1 -InformationAction Ignore # writes an error
Test-Inf2 -InformationAction Ignore # okay

Похоже, то же самое относится и к авторам, пишущим командлеты на C #.

@GeeLaw

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

Ой! Извините - не заметил свою опечатку.

просто устанавливает соответствующую предпочтительную переменную внутри вызванного командлета.

Да, а остальное из того, что вы демонстрируете, является предметом вышеупомянутого # 1759.

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

Более конкретно:

В 5.1 и 6.0.2 InformationAction не принимает Ignore, что можно продемонстрировать в следующем фрагменте:

Поскольку это имеет значение для решения проблемы, позвольте мне указать, что -InformationAction _does_ принимает Ignore , и только указанный недостаток конструкции вызывает проблему, если и когда предпочтение применяется_ в контексте of _advanced functions_, который в вашем случае является Write-Information call _inside_ функции.
Эта проблема сохраняется, начиная с версии PowerShell Core v6.1.0-preview.2.

_Скомпилированные командлеты_, напротив, не имеют этой проблемы, поэтому Write-Host foo -InformationAction Ignore работает по назначению, например, как вы с тех пор обнаружили.

Подводя итог, мы обсуждали здесь две не связанные между собой проблемы:

  • Недостаток дизайна в отношении Ignore в качестве значения переменной предпочтения действия, который уже отслеживается в # 1759.

  • Исходная тема этой проблемы, некорректно работающий командлет Test-Connection , который по ошибке использует тег PSHOST в своих вызовах .WriteInformation .

Решением последнего является просто _omit_ тег, как показано в следующем примере:

# With $InformationAction at its default, 'SilentlyContinue', this invocation is silent.
# If you set it to 'Continue', 'foo' prints.
& { [CmdletBinding()]param() $PSCmdlet.WriteInformation('foo', [string[]] @()) } 

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

В прошлом году я отправил PR (№ 2537), чтобы добавить Test-Connection в код, и он был отклонен в то время, потому что «@ PowerShell / powershell-Committee не примет этот PR, так как он приведет к проблемам совместимости в будущем», поэтому я был удивлен, увидев включение этого командлета сейчас, но не с кодом исходного PR, а с совершенно новым кодом, который не обеспечивает всей ожидаемой функциональности.

Самая большая проблема, с которой я сталкиваюсь, заключается в том, что в моих сценариях я выполняю такие проверки, как «if (Test-Connection 8.8.8.8 -Quiet)», чтобы перейти в мою логику, но с параметром -Quiet, который не соблюдается, ветвь всегда возвращает True. потому что нет ни False, ни Null. Таким образом, это делает команду по-прежнему совершенно непригодной для меня, а также, поскольку она включена в новые выпуски PowerShell, это делает обновление очень болезненным для меня. Пожалуйста, исправьте это, так как похоже, что прошло несколько месяцев с момента первого сообщения о проблеме. Либо это, либо восстановление исходного PR не имеет значения, пока функциональность возвращается.

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

Если у нас есть Test-Connection в 5.1 и 6.x, я ожидаю, что они будут иметь такой же результат. Я знаю, что реализация отличается, но пользователей это не должно волновать. Текущее тестовое соединение в 6.1 ведет себя иначе, давая нам другой результат, чем в 5.1. Кроме того, параметр -Quiet практически бесполезен.

Кажется, эта проблема все еще существует, на данный момент (PSVersion = 6.2.0) командлет продолжает отображать информацию «ping», даже если присутствует QUIET (добавление «-InformationAction Ignore» помогает, но это означает, что модули / скрипты используют командлет Test-Connection надо будет обновить, не круто)

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

cc @ SteveL-MSFT @iSazonov

Я возвращаюсь к этому время от времени. Теперь я считаю, что мы могли бы решить эту проблему, используя явное разделение интерактивных и неинтерактивных сценариев с переключателем -Intercative . С помощью параметра мы могли бы реализовать богатый и удобный вывод в консоль. Похоже, пользователю не так уж и неудобно вводить этот параметр (как "-i"). Без переключателя мы бы получали строго типизированный вывод без подробного вывода на консоль, что хорошо для сценариев сценария.

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

Например, посмотрите Get-ChildItem. В интерактивном режиме это очень полезно благодаря отображению средства форматирования по умолчанию. Никаких изменений не требуется, чтобы сделать его полезным для автоматизации; та же команда, которая работает в интерактивном режиме, также работает в сценарии.

Я чувствую, что это излишняя сложность.

Мы могли бы сделать интерактивный вывод по умолчанию и улучшить параметр Quiet чтобы подавить вывод в скриптах.

Опять же ... Я не вижу необходимости иметь другой вывод в интерактивном режиме и в сценариях.

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

-Quiet - это переключатель, используемый исходным командлетом в Windows PowerShell для выдачи чистого ответа True / False вместо вывода объектов. На мой взгляд, нарушение этого соглашения - плохая идея.

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

Опять же ... Я не вижу необходимости иметь другой вывод в интерактивном режиме и в сценариях.

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

вывод всех своих данных в сложный для захвата или синтаксического анализа текстовый поток

Командлет выполняет вывод строго типизированных объектов. (Проблема в том, что невозможно построить эти объекты и отобразить их одновременно из-за наличия «мета» информации.)

-Quiet - это переключатель, используемый исходным командлетом в Windows PowerShell для выдачи чистого ответа True / False вместо вывода объектов. На мой взгляд, нарушение этого соглашения - плохая идея.

Этот командлет Windows PowerShell поддерживает только проверку связи, для которой не существует концепции подключения. Изначально это была спорная конструкция. Правильное имя для них будет Test-Ping ot Test-ICMP .
Текущий командлет поддерживает IP-подключения. Хотя я бы предпочел что-то вроде "Test-Connectivity".

В своей текущей итерации он ведет себя больше, чем можно было бы ожидать от утилиты Unix, что сильно отличается от того, как работают другие командлеты PowerShell.

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

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

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

@iSazonov Я не согласился с вами после первого прочтения, НО после тестирования я понимаю вашу точку зрения

$a=Test-Connection www.microsoft.com 
$b=Test-Connection www.microsoft.com -Quiet

Значения $ a и $ b - это то, что я ожидал, НО мне не нужен дополнительный вывод.

Select-String также имеет тихий параметр и не имеет ничего общего с "интерактивным" поведением.

Я согласен, что этой команде нужен дополнительный параметр для изменения поведения (Тихо или нет).

Я предпочитаю параметр «Интерактивный» не по умолчанию, но, возможно, параметр переключателя «NoInteractive» - лучшая настройка, позволяющая установить приоритет при интерактивном использовании.

Хорошо, вот что я считаю несколько более полезной реализацией.

Общие моменты

  1. Весь текущий вывод информации о хосте / информации направляется в поток -Verbose . В настоящее время это не используется _ вообще_, и это идеальный вариант использования.
  2. Нет индикатора выполнения, если он не указан переключателем -ShowProgress .
  3. Удалите переключатель -Ping (это поведение по умолчанию).

Первичный выход

Test-Connection www.google.com

  • Информация из свойства Replies выходного объекта должна быть включена в основной выходной объект, а основной выходной режим должен быть _multiple_ объектами, каждый из которых представляет один объект попытки проверки связи / ответа.
  • Буфер _data_ обычно не имеет значения, так как он не может быть указан, и должно быть открыто только свойство BufferSize . Replies.Buffer свойство должно оставаться private .
  • Свойство Replies.Options должно быть скрыто от форматирования по умолчанию.
  • Результаты выводятся в виде таблицы, сгруппированной по адресу назначения (в случае, если указано несколько мест назначения).

Выходной визуальный макет

Используемая команда:

$Result = Test-Connection www.google.com
$Data = foreach ($Reply in $Result.Replies) {
    [PSCustomObject]@{
        Source = $Result.Source
        Destination = $Result.Destination
        Address = $Reply.Address
        RoundtripTime = $Reply.RoundtripTime
        BufferSize = $Reply.Buffer.Length
        Options = $Reply.Options
    }
}
$Data | Format-Table -GroupBy Destination -Property Source, Address, RoundtripTime, BufferSize

Результат:

   Destination: www.google.com
Source  Address       RoundtripTime BufferSize
------  -------       ------------- ----------
WS-JOEL 172.217.2.132            36         32
WS-JOEL 172.217.2.132            21         32
WS-JOEL 172.217.2.132            25         32
WS-JOEL 172.217.2.132            25         32

Test-Connection www.google.com -TraceRoute

  • Каждый прыжок должен выводиться как отдельный объект, каждый из которых содержит объекты PingReply в качестве свойства, доступного путем скрытия от форматирования.
  • Основной объект TraceRouteResult должен содержать свойства ETS или класса, которые вычисляют сводные данные на основе своих четырех ответов PingReplies.
  • Примечание. Этот тип объекта, который мы используем, в настоящее время содержит ошибки , и все объекты PingReply сообщают о своем статусе TtlExpired . Рекомендуем изучить ход исправления для .NET Core 3 или разработать собственное решение для поддержки TraceRoute, чтобы решить эту проблему.
  • Вывод в виде таблицы, сгруппированной по DestinationHost (Почему это имя свойства отличается от имени другого типа объекта, используемого для стандартных проверок связи?)

Выходной визуальный макет

Используемая команда:

$Result = Test-Connection www.google.com -TraceRoute
$Data = foreach ($Reply in $a.Replies) {
    [PSCustomObject]@{
        Hop = $Reply.Hop
        Source = $a.Source
        Destination = $a.DestinationHost
        DestinationAddress = $a.DestinationAddress
        Replies = $Reply.PingReplies
        RoundtripTimes = $Reply.PingReplies.RoundtripTime
        HopAddress = $Reply.PingReplies[0].Address
        BufferSize = $Reply.PingReplies.ForEach{$_.Buffer.Length}
        Options = $Reply.PingReplies[0].Options
    }
}

$Data | Format-Table -GroupBy Destination -Property Hop, RoundtripTimes, DestinationAddress, HopAddress, BufferSize

Результат:

   Destination: www.google.com
Hop RoundtripTimes DestinationAddress HopAddress     BufferSize
--- -------------- ------------------ ----------     ----------
  1 {0, 0, 0}      172.217.2.132      192.168.22.254
  2 {0, 0, 0}      172.217.2.132      75.144.219.238
  3 {0, 0, 0}      172.217.2.132      96.120.37.17
  4 {0, 0, 0}      172.217.2.132      96.110.136.65
  5 {0, 0, 0}      172.217.2.132      69.139.180.170
  6 {0, 0, 0}      172.217.2.132      68.85.127.121
  7 {0, 0, 0}      172.217.2.132      68.86.165.161
  8 {0, 0, 0}      172.217.2.132      68.86.90.205
  9 {0, 0, 0}      172.217.2.132      68.86.82.154
 10 {0, 0, 0}      172.217.2.132      66.208.233.242
 11 {0, 0, 0}      172.217.2.132      0.0.0.0
 12 {0, 0, 0}      172.217.2.132      216.239.59.124
 13 {0, 0, 0}      172.217.2.132      216.239.59.61
 14 {32, 28, 20}   172.217.2.132      172.217.2.132

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

О, @ vexx32 Я вижу, ты никогда не диагностировал сеть. Ваше предложение было реализовано мной на первом этапе, а затем отклонено как непригодное для использования в интерактивном сеансе. Например, мы можем очень долго смотреть на пустой экран после выполнения команды Test-Connection www.google.com -TraceRoute . Поэтому реализация была изменена, чтобы отображать вывод (строку или индикатор выполнения) для каждого ответа.

Весь текущий хост / вывод информации передается в поток -Verbose. В настоящее время он вообще не используется, и это идеальный вариант использования.

Мое предложение выше заключалось в том, чтобы ввести переключатель Interactive для разделения интерактивных сценариев и сценариев. Вы предлагаете сделать то же самое с переключателем Verbose что еще более неестественно.

Нет индикатора выполнения, если он не указан с помощью переключателя -ShowProgress.

Строковый вывод и индикатор выполнения находятся в текущей реализации как две альтернативы. Нам нужен только один. Индикатор выполнения используется в командлете Windows PowerShell. Я предпочитаю вывод строк в интерактивном сеансе. Это намного удобнее.
И мы никогда не подавляем индикатор выполнения переключателем. У нас есть $ ProgressPreference для сценариев сценариев. Некоторые командлеты показывают индикатор выполнения только для длительных операций по таймеру.

Удалите переключатель -Ping (это поведение по умолчанию).

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

Ваше предложение было реализовано мной на первом этапе, а затем отклонено как непригодное для использования в интерактивном сеансе. Например, мы можем очень долго смотреть на пустой экран после выполнения команды Test-Connection www.google.com -TraceRoute. Поэтому реализация была изменена, чтобы отображать вывод (строку или индикатор выполнения) для каждого ответа.

Отображение прогресса не требуется для формата разделенных объектов, так как мы можем довольно легко увидеть прогресс, когда каждый объект отправляется на вывод. Единственная причина, по которой он здесь нужен, заключается в том, что мы не выводим данные в конвейер, поскольку они извлекаются, как любой другой командлет PowerShell. Если мы выводим каждый PingReply или переход по трассировке для -TraceRoute мы _имеем_ отображение прогресса, встроенное в отображение вывода.

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

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

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

Я ни здесь, ни там по этому поводу, но обычно поведение командлета по умолчанию не имеет переключателя. Например, у нас нет переключателя -Loud противоположного -Quiet .

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

С вашим предложением выше мы собираем объекты "ping" в "meta" объекте, и невозможно вывести объекты "ping" в реальном времени - мы можем выводить в конвейере только объект "meta" - пользователь всегда будет видеть пустой дисплей.

-Verbose - это общий параметр и, таким образом, гораздо более естественный выбор для командлета, чем совершенно новый переключатель.

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

обычно поведение командлета по умолчанию не имеет переключателя.

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

С вашим предложением выше мы собираем объекты "ping" в "meta" объекте, и невозможно вывести объекты "ping" в реальном времени - мы можем выводить в конвейере только объект "meta" - пользователь всегда будет видеть пустой дисплей.

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

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

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

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

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

Мета-объект не нужен.

_Это критически необходимо._
Такой подход делает командлет бесполезным. Если у вас есть сеть, в которой есть проблемы, попробуйте запустить диагностику с помощью этого командлета. Ты не сможешь это сделать. Кидаешь и возьмешь утилиты ping и traceroute. Но теперь такую ​​же диагностику с новым командлетом можно делать как в консоли, так и, например, в системе мониторинга с помощью скрипта. Я понимаю, что это сложно понять, если вы не делаете регулярную диагностику сети. Посмотрите, сколько параметров имеют эти собственные утилиты, особенно в версиях Unix. Все они важны для диагностики. Искусство диагностики заключается в использовании их сочетаний и магических значений. Я попробовал все это добавить в новый командлет.

Я просто считаю это пустой тратой времени

Использование позиционных параметров поможет вам :-)

Краткое описание комитета PowerShell.

Текущий командлет был разработан

  • чтобы получить переносимый командлет для всех поддерживаемых платформ. На самом деле у нас все еще есть некоторые проблемы в .Net Core, поэтому не все функции работают на формах Unix.
  • чтобы получить возможности популярных инструментов, таких как ping, traceroute, pathping, Portqry.exe и т. д.
  • получить полезные выходные объекты в __scripts__, подходящие как для простого, так и для углубленного анализа доступности сети
  • чтобы получить полезный вывод консоли с _header_ и _footer_. Обратите внимание, что в некоторых сценариях командлет отображает даже более полезную информацию, чем служебная программа для создания прототипов.
  • чтобы позволить будущие улучшения, такие как удаленное тестирование "Test-Connection -Source ... -Destination ..."

Основная проблема заключается в том, как совместить вывод интерактивной консоли (интерактивный сценарий) и вывод объектов в конвейере (сценарий сценария). Мое текущее предложение - сделать разделение либо с помощью параметра (-Interactive), либо с помощью нового командлета (Show-Connectivity для интерактивного сценария и Test-Connectivity для сценария сценария).
Также я бы предложил изменить имя командлета на Test -__ Connectivity__, что более точно. Это также позволит бесплатно использовать старый командлет Windows через прокси (WCM) без конфликта имен.

@iSazonov, можете ли вы привести пример такой диагностики, которая требует наличия мета-объекта, скрывающего все данные? Я предлагаю переместить информацию из мета-объекта в каждый объект PingReply; Я не понимаю, как это уменьшит полезность командлета.

Как вы помещаете статистику из нижнего колонтитула в первый объект «ping», если вы выводите объект сразу после создания?

Какая информация в нижнем колонтитуле? Единственная информация нижнего колонтитула от пинга - Ping complete.

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

Дело здесь в том, чтобы командлеты (в данном случае Test-Connection) оставались одинаковыми в обеих версиях (WinPS и Pwsh), добавляя переключатель в командлет, чтобы в этом случае `` отключить '' этот вывод был бы неправильным, поскольку, как я сказал прежде чем это будет означать, что каждый скрипт / модуль, использующий этот командлет, должен быть обновлен, решение делает это одинаково для обеих версий

Командлет @ NJ-Dude Windows основан на WMI и его невозможно перенести с обратной совместимостью. Также заморозили 5.1 - в дальнейшем никаких дополнений не будет.

Командлет @ NJ-Dude Windows основан на WMI и его невозможно перенести с обратной совместимостью. Также заморозили 5.1 - в дальнейшем никаких дополнений не будет.

Я понимаю и знаю это, я просто говорю, что SYNTAX и функциональность должны быть одинаковыми, что означает, что если использование QUIET не отображает никаких выходных данных, они не должны отображать какие-либо выходные данные независимо от используемого типа PS.

Я просто говорю, что SYNTAX и функциональность должны быть одинаковыми

Это невозможно. Модуль совместимости с Windows - единственный способ получить старую функциональность.

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

Нет _не других командлетов_, которые ведут себя таким образом, когда наиболее полезные данные находятся в строковой форме в информационном потоке. У него нет причин так себя вести. Все данные должны быть в потоке вывода, точка . Дополнительные данные находятся в подробных потоках или потоках отладки по мере необходимости. Подобное использование информационного потока совершенно беспрецедентно для командлета, поставляемого с самой PowerShell.

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

В очереди на обсуждение комитета

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

  • Данные должны выводиться построчно. Я думаю, что это текущий случай с Test-Connection s и ping.exe и др.
  • Данные должны быть возвращены как структурированный объект. Форматирование не должно учитывать этот факт. (Как бы ужасно это ни было, я видел средство форматирования, которое выдает на консоль строку JSON, несмотря на то, что это PSObject под капотом. Я просто хочу сказать, что это можно сделать.) Форматирование - это также место, где мы нам разрешено изменять все, что мы хотим, без нарушения изменений. (Также полностью согласен с @ vexx32, что мы должны быть осторожны с заголовками столбцов, которые не соответствуют названиям свойств. Иногда это необходимо для удобства чтения, но это также сводит меня с ума.)
  • -Quiet должен выдавать ничего, кроме True / False как логическое значение, как и Windows PowerShell.
  • Если нам нужно передать больше информации, чем случай по умолчанию (который должен быть больше, чем минимальное логическое значение -Quiet case), -Verbose звучит разумно, но я еще не подумал об этом достаточно. (Здесь также я теряю нить, трудно сказать, что еще люди хотят наверху).
  • Имитация одного и того же объекта ( cimv2\Win32_PingStatus ) со всеми теми же свойствами, что и Windows PowerShell, невозможно (из-за .NET Core, WMI и т. Д.), Но мы должны попытаться получить его как можно ближе.
  • Я не знаю о прогрессе. Я считаю, что прогресс по-прежнему сводит всех с ума, потому что он медленный (несмотря на нашу оптимизацию), но также и то, что в неинтерактивном режиме он не имеет большого значения, потому что все в любом случае устанавливают $ProgressPreference .

Звучит неплохо!

Прогресс в основном меня чертовски раздражает, потому что он не может быть обработан в вызове команды; вам нужно установить $ ProgressPreference. Я действительно хотел бы, чтобы это был общий параметр ... Но у меня есть еще одна проблема, поэтому давайте не будем здесь вдаваться в подробности! :улыбка:

@ PowerShell / комитет по PowerShell рассмотрел это. Мы договорились, что Test-Connection должен максимально точно имитировать поведение, как в Windows PowerShell 5.1 (включая -Quiet ). Это означает, что объект вывода PingStatus (отбрасывая win32_ ) должен генерироваться для каждого ответа, имеющего свойства в формате по умолчанию и любых дополнительных, которые доступны. Прогресс не следует использовать.

Кто-нибудь захочет написать короткий RFC, который показывает синтаксис командлета вместе с предлагаемым форматом вывода для просмотра?

@ stevel-msft Я был бы счастлив. :)

Мне нравится это звучание.
благодаря

Довольно интересно, что PR 3125 охватил все это, но использование Test-Connection было отклонено, но теперь мы прошли полный круг. А как насчет того, чтобы оглянуться на 3125?

Если взглянуть на него вкратце, похоже, что он по сути заменил Test-Connection другой реализованной командой на платформах Unix, чтобы попытаться подражать команде Windows? Я правильно читаю?

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

Я брошу ссылку на черновик RFC, когда закончу его писать, и не стесняйтесь комментировать, корректировать и т. Д. Я хотел бы услышать еще несколько точек зрения по этому поводу. 🙂

РЕДАКТИРОВАТЬ: https://github.com/PowerShell/PowerShell-RFC/pull/172

Мой конкретный вариант использования подсказки был основан на желании использовать PowerShell Core в Linux, но реализация была полностью протестирована как в Windows, так и в Linux. Это было предназначено для полной замены отсутствующей команды.

Когда мы это увидим? В 6.2.2? Когда это, вероятно, приземлится?
(было забавно видеть, как эта ветка бушевала с апреля 2018 года по настоящее время из-за того, что _-quiet_ был шумным. Кажется, такое несложное изменение)

Мне кажется, я могу написать этот код довольно легко, я просто жду, когда RFC будет принят. Вскоре, как это произойдет, я сделаю это и отправлю PR для этого. :улыбка:

О, я думал, что статус таков, что он был одобрен (не зная точно, какие есть состояния или каков полный процесс). Но спасибо за обновление. Еще жаль, что на то, чтобы успокоить, ушло больше 12 месяцев :)

более 12 месяцев, чтобы было тихо

Я ожидал большего отклика

@ vexx32, вы можете начать кодировать это и поставить его под экспериментальный флаг на случай, если появится какая-либо обратная связь, которая изменит текущее предложение

@ SteveL-MSFT У меня уже есть в основном работающая реализация. Я скоро отправлю PR с некоторыми экспериментальными флагами, чтобы мы могли поговорить о коде более конкретно. 💖

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

Не могли бы вы подробнее рассказать, как, по вашему мнению, может сработать @isazonov?

@ vexx32 Вы спрашиваете о реализации или UX-дизайне?

Я думаю, в основном то, чем, по вашему мнению, будет для этого UX. :)

В интерактивной сессии лучший UX - это
1. минимальный набор текста
Это означает:
- пинг по умолчанию
- переход в другой режим (traceroute и др.) с одним параметром
2. удобный вывод
Это означает:
- эмулировать вывод ping.exe (tracert.exe и другие) _на консольный хост_, как я пробовал в демонстрационном коде - с хорошо отформатированными заголовками, нижними колонтитулами и информативными строками. Не нужно думать о типах вывода - они не используются, а только отображаются.
- добавить параметры для переключения в режим сценария - то есть подавить вывод удобного текста на хост консоли и выдать строго типизированные объекты. Нет необходимости форматировать этот вывод. Мы обсудили Quiet, который возвращает True / False, но нам нужен параметр (ы) для выдачи других необработанных строго типизированных объектов (например, -RawOutput). Допустимо использование дополнительных параметров в скриптах.

Спасибо, мне кажется, я теперь немного лучше понимаю, о чем вы понимаете.

Я действительно не вижу необходимости в таком двойном режиме? Никакие другие командлеты в PowerShell не разделяют интерактивные параметры и параметры «режима сценария».

Если вам нужен точный вывод команды ping / tracert, почему бы вам просто не использовать эти утилиты напрямую?

PowerShell никогда не прилагал значительных усилий для полной имитации существующей команды; Я думаю, что Get-ChildItem, вероятно, самый близкий, но почти единственный, который делает это.

Если бы мы хотели полностью эмулировать отображение ping / tracert, как вы говорите, я бы предложил вместо этого использовать это как отдельный командлет или функцию, например Show-Connection , а не загромождать Show-Command дополнительными параметрами, которые не существуют. прецедент или необходимость в PowerShell.

Я действительно не вижу необходимости в таком двойном режиме? Никакие другие командлеты в PowerShell не разделяют интерактивные параметры и параметры «режима сценария».

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

Если вам нужен точный вывод команды ping / tracert, почему бы вам просто не использовать эти утилиты напрямую?

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

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

Да, вы отлично поработали с ним! Я очень ценю это. Текущий режим вывода бесполезен для чего-либо, кроме интерактивного использования. Мы могли бы просто удалить шаг вывода и назвать его Show-Connection а затем использовать то, что вы написали, в решении, более ориентированном на PowerShell, для самого Test-Connection , как я описываю в RFC.

@ vexx32 Я только что попробовал ваш PR, и он немного улучшил его, но я заметил, что в Windows PowerShell он посылает PingReply индивидуально в конвейер, поэтому вы получаете что-то вроде:

PS C:\Users\slee> Test-Connection localhost

Source        Destination     IPV4Address      IPV6Address                              Bytes    Time(ms)
------        -----------     -----------      -----------                              -----    --------
SLEE-DESKTOP  localhost       127.0.0.1        ::1                                      32       0
SLEE-DESKTOP  localhost       127.0.0.1        ::1                                      32       0
SLEE-DESKTOP  localhost       127.0.0.1        ::1                                      32       0
SLEE-DESKTOP  localhost       127.0.0.1        ::1                                      32       0

Однако с вашим изменением все ответы ping являются членами одного объекта:

PS> Test-Connection localhost

Source       Destination Replies
------       ----------- -------
slee-desktop localhost   {System.Net.NetworkInformation.PingReply, System.Net.NetworkInformation.PingReply, System.Net.NetworkInformation.PingReply, System.Net.N…

Неужели мы не можем вернуть поведение Windows PowerShell?

@ SteveL-MSFT Этот вывод объекта не изменился по сравнению с первоначальной реализацией в PS Core; результат успеха всегда имел единственный объект. 🙂

Как упоминалось в заключительных комментариях к PR, это лишь частичная реализация RFC для упрощения проверки. Вскоре я отправлю следующий PR. Просто нужно перебазировать эту ветку, чтобы удалить повторяющиеся коммиты, и отправить оставшуюся часть, чтобы приблизиться к истинному паритету с реализацией Windows PowerShell. Он все равно будет несколько отличаться (как видно из RFC, который мы рассмотрели несколько недель назад), но, надеюсь, будет гораздо более универсальным. 😊

@ SteveL-MSFT см. # 10697, чтобы узнать о следующей главе этого приключения! 😊

: tada: Эта проблема устранена в выпуске # 10478, который теперь успешно выпущен как v7.0.0-preview.5 .: tada:

Полезные ссылки:

В версии 7.0.0 Test-Connection -Quiet по-прежнему дает
Тестовое соединение: не удалось проверить соединение с компьютером, «очищенным»: не удалось разрешить целевое имя.
вместо
Ложь

@chvol, не могли бы вы открыть для этого новый выпуск как можно подробнее?

Благодаря! 🙂

Была ли эта страница полезной?
0 / 5 - 0 рейтинги