Powershell: Test-Connection cmdlet显示不需要的数据。

创建于 2018-04-28  ·  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标签,该标签实际上_bypasses_ $InformationActionPreference值以及-InformationAction SilentlyContinue (但如上所述) , -InformationAction Ignore _is_在抑制输出方面有效)。

WriteInformation()调用所做的实际上是Write-Host所做的操作,以便(通过设计)无条件地显示其输出。

@iSazonov :我还没有真正查看带有进度条的其他cmdlet的行为,但是有了-Quiet ,即使交互调用,我也不会期望进度条。

所有64条评论

在5.1中可以正常运行,但在6中则不能,因此我将问题重新分类为bug。

原因是当前代码调用WriteInformation (盲目?)。

参见TestConnectionCommand.cs的751行,还有775行和783行。

暂时的解决方法是使用InformationAction公共参数来阻止信息显示到主机。 例:

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

脚本的角度来看,这不会成为问题,因为文本信息永远不会写入管道,并且不,文本输出也不是结果数据的一部分,结果数据被定义为发送到管道的事物。 同样, Quiet开关被定义为返回更简单的结果( intbool ,而不是记录对象)。 我必须承认,可能不会期望InformationRecordQuiet在一起。 但是,知道原因之后,我说我们最好使InformationActionQuiet解耦。

在PowerShell 5.1中, Test-Connection似乎根本没有调用WriteInformation 。 顺便说一句,在PowerShell 5.1和PowerShell Core 6.0.2中, $InformationPreference的默认值为SilentlyContinue 。 问题的作者在复制问题时可能具有不同的有效价值。 (也许PS 6.1 Core更改了$InformationPreference的默认值?我不确定。)

如果PS 6.1 Core的$InformationPreference默认为SilentlyContinue ,则文本信息将不存在,除非用户明确要求。

我需要更多反馈。
问题在于,在脚本模式和交互模式下,它应该以不同的方式工作。 在交互模式下,用户可能更喜欢通过ping.exe命令查看进度(栏)。 这也适用于其他参数。

@ mklement0如果您有时间,那么您的帮助将非常有用。

@GeeLaw

很好的发现,但是在这种情况下,需要-InformationAction Ignore来解决错误。

$InformationActionPreference仍然默认为SilentlyContinue ,并且应该保持不变。

该错误是您链接到的WriteInformation()错误地使用了PSHOST标签,该标签实际上_bypasses_ $InformationActionPreference值以及-InformationAction SilentlyContinue (但如上所述) , -InformationAction Ignore _is_在抑制输出方面有效)。

WriteInformation()调用所做的实际上是Write-Host所做的操作,以便(通过设计)无条件地显示其输出。

@iSazonov :我还没有真正查看带有进度条的其他cmdlet的行为,但是有了-Quiet ,即使交互调用,我也不会期望进度条。

@ mklement0感谢您的答复和对PSHostTag的更正。 在我看来, InformationPreferenceInformationAction )将不接受Ignore吗? 在5.1和6.0.2中都是如此。 也许在6.1中已更改。 (是InformationActionPreference一个新的别名InformationPreference ?)

另外,我的第一条评论是错误的,因为它会将InformationActionContinue 。 正确的解决方法是通过将流6(信息流)重定向到$null来丢弃它,即,

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

通过以下方法检查正确性:

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

它不应向主机写入任何内容。

@GeeLaw

在我看来,InformationPreference(InformationAction)将不接受忽略吗?

是的,_preference变量_不接受Ignore ,但是_common parameter_可以。

也就是说,对于给定的调用,您可以抑制信息流(编号6 ),但对于整个作用域,则不能_categorically_(根据设计)。

因此,以下两个语句是等效的:

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作为操作_preference variables_的值:

  • 此限制存在一个基本的设计问题,因为自动定义的局部首选项变量用于在高级函数内传播公共参数值-请参阅#1759

  • 该限制不会在_assignment time_强制执行,这意味着直到下一次(可能是隐式)应用了首选项之前,您不会看到问题-请参阅#4348

    • 更笼统地说,在除全局范围之外的任何范围内,根本不执行任何验证。 比较$ErrorActionPreference = 'bogus'& { $ErrorActionPreference = 'bogus' } -请参阅

      3483。

@ mklement0我在问别名,因为您将其称为InformationActionPreference

据我所知, -XxxAction (以及-Verbose-Debug )只是在调用的cmdlet中设置相应的首选项变量。 如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实际上接受的范围比相应的公共参数可以设置的范围要大。 例如,可以通过显式分配将$VerbosePreferenceInquire ,但不能使用-Verbose开关,因为毕竟这是一个开关并映射$True / $FalseContinue / SilentlyContinue

据我所知,除了那两个开关之外,与优先级相关的通用参数正好映射到本地范围内的相应优先级变量。

另一轮测试显示了以下代码:

Write-Information 'writing' -InformationAction Ignore

但这对开发人员来说很麻烦,因为我们必须用支票$InformationAction -eq '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#编写cmdlet的作者。

@吉律

我问别名是因为您提到它为InformationActionPreference。

糟糕! 抱歉-没注意到我自己的错字。

只需在调用的cmdlet中设置相应的首选项变量。

是的,您演示的其余内容是上述#1759的主题。

简而言之:设计缺陷是不允许Ignore作为首选项变量值与使用自动设置的本地首选项变量实例以传播公共参数值相冲突。

进一步来说:

在5.1和6.0.2中,InformationAction不接受忽略,如以下代码片段所示:

由于与解决问题有关,因此,我要指出-InformationAction _does_接受Ignore ,并且仅是说设计缺陷会导致问题_if和何时应用首选项_高级函数_,在您的情况下是Write-Information调用_inside_函数。
从PowerShell Core v6.1.0-preview.2开始,此问题仍然存在。

相比之下,_Compiled cmdlets_不存在此问题,这就是为什么Write-Host foo -InformationAction Ignore可以按预期工作的原因,例如,您从此以后就发现了。

总而言之,我们在这里讨论了两个不相关的问题:

  • 关于Ignore作为操作偏好变量值的设计缺陷,已在#1759中进行了跟踪。

  • 此问题的原始主题是行为不当的Test-Connection cmdlet,它在对.WriteInformation调用中错误地使用了PSHOST标签。

后者的解决方案是简单地_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,因为它将来会引入兼容性问题”,因此,我很惊讶地看到现在包含了此cmdlet,但没有包含原始PR的代码,而是未提供所有预期功能的全新代码。

我遇到的最大问题是在脚本中执行如下检查:“ if(Test-Connection 8.8.8.8 -Quiet)”以分支到我的逻辑中,但是在不遵守-Quiet参数的情况下,该分支始终返回True因为没有False或Null。 因此,这使该命令仍然对我完全不可用,并且由于该命令已包含在PowerShell的新版本中,因此升级对我来说非常棘手。 请修复此问题,因为自首次报告此问题以来已经过去了几个月。 只要返回功能,要么恢复原始PR,要么无关紧要。

去年我确实提交了PR,以将Test-Connection添加到代码中,但当时被拒绝了,因为他们不想添加旧式cmdlet,所以我很惊讶地看到现在包含了此cmdlet,但没有包含代码完整的原始PR,其功能与“旧版”完全相同。

如果我们在5.1和6.x中具有Test-Connection,我希望它们具有相同的输出。 我知道实现方式有所不同,但用户不必在意。 当前6.1中的Test-Connection的行为与5.1中的不同,从而为我们提供了不同的输出。 除此之外,-Quiet参数实际上是无用的。

似乎此问题仍然存在,截至目前(PSVersion = 6.2.0),即使存在QUIET,该cmdlet仍将继续显示“ ping”信息(添加“ -InformationAction Ignore”可以解决问题,但这意味着模块/脚本使用Test-Connection cmdlet将必须更新,而不是很酷)

如果我们能在7.0中解决这个问题,那就太好了。 我很乐意提供代码,但是我们需要遵循一个实现规范,因为在早期尝试中对此没有什么共识。

抄送@ SteveL-MSFT @iSazonov

我不时回到这个问题。 现在,我相信我们可以通过使用带有-Intercative开关的显式分离交互式和非交互式方案来解决此问题。 使用该参数,我们可以实现丰富的用户友好控制台输出。 用户键入该参数(如“ -i”)似乎不太方便。 如果没有切换,我们将执行强类型输出,而没有适用于脚本场景的详细控制台输出。

鉴于没有其他cmdlet使用此类参数,因此我认为具有这种双重性是没有道理的。 cmdlet应该完成其任务并保持一致的行为; 互动行为不应与其他行为分开。

例如,查看Get-ChildItem。 交互式地,由于默认的格式化程序显示,它非常有用。 无需更改也可以使其对自动化有用。 交互工作的同一命令也可以在脚本中工作。

我觉得那是不必要的复杂性。

我们可以默认进行交互式输出,并增强Quiet参数以抑制脚本中的输出。

再说一遍...我不认为需要交互式地提供与脚本中不同的输出。

如果该cmdlet的行为与其他cmdlet一样,并且输出的是无法使用的数据,而不是完全唯一的,并且在难以捕获或解析的文本流中输出所有数据(这是_PowerShell_,而不是Bash),则绝对不需要更改行为。

-Quiet是Windows PowerShell中原始cmdlet用来提供纯True / False响应而不是输出对象的开关。 我认为打破常规是一个坏主意。

此cmdlet的行为应与现有cmdlet一致。 没有理由让它单独使用当前行为。 在当前的迭代中,它的行为更像是人们期望Unix实用程序运行的方式,与其他PowerShell cmdlet的运行方式完全不同。

再说一遍...我不认为需要交互式地提供与脚本中不同的输出。

您可以在所有受支持的场景中演示所需的输出吗? 请注意,cmdlet输出的元信息非常重要。

将所有数据输出到难以捕获或解析的文本流中

该cmdlet进行强类型对象输出。 (问题在于,由于存在“元”信息,因此无法构建这些对象并同时显示)。

-Quiet是Windows PowerShell中原始cmdlet用来提供纯True / False响应而不是输出对象的开关。 我认为打破常规是一个坏主意。

Windows PowerShell cmdlet仅支持不存在连接概念的ping。 最初这是有争议的设计。 他们的正确名称是Test-PingTest-ICMP
当前的cmdlet支持ip“连接”。 尽管我更喜欢“测试连通性”之类的东西。

在当前的迭代中,它的行为更像是人们期望Unix实用程序运行的方式,与其他PowerShell cmdlet的运行方式完全不同。

不,该cmdlet可以输出强类型的对象。 控制台输出看起来像实用程序。 但同时,您可能会看到它实际上更丰富,更有用。
问题在于无法使用格式化子系统的功能来获得此输出,因此有必要将其直接输出到控制台。 (请注意,这不会与输出流中的输出对象混淆)

如果我们以更健壮的方式构造数据对象,则可以使用格式化系统获得输出。 我已经提交了带有原型的PR。 通常,以某种方式显示数据的cmdlet不能正确反映基础对象数据(例如,通过显示子属性中的数据而不是正确地构造对象类),在我看来,应该尽可能避免这种情况。

我将对此进行进一步的研究,并给出一个更完整的示例,说明我认为期望的输出。 Windows PowerShell中的Test-Connection可能是一个有争议的设计,但我认为这是朝着正确方向迈出的一步,即使这是非常不完整的。

@iSazonov我不同意测试后的第一次阅读但我理解您的观点

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

$ a和$ b值是我期望的,但是我不希望有多余的输出。

选择字符串也有一个安静的参数,它与“交互”行为无关

我同意该命令需要一个附加参数来更改行为(是否静音)。

我更喜欢默认情况下不使用参数“ Interactive”,但最好使用开关参数“ NoInteractive”来更好地调整交互式使用的优先级。

好了,这就是我认为是更有用的实现。

一般要点

  1. 当前所有主机/信息输出都降级为-Verbose流。 目前还没有使用过,这是一个完美的用例。
  2. 除非使用-ShowProgress开关指定,否则没有进度条。
  3. 删除-Ping开关(这是默认行为)。

主要输出

Test-Connection www.google.com

  • 来自输出对象的Replies属性的信息应包含在主输出对象中,主输出模式应为_multiple_对象,每个对象代表一个ping尝试/答复对象。
  • 缓冲区_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分组(为什么此属性名称与用于标准ping的其他对象类型的名称不同?)

输出视觉模型

使用的命令:

$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 cmdlet中使用了进度条。 我的首选是在交互式会话中输出字符串。 这更加方便。
而且,我们绝不会通过开关抑制进度条。 对于脚本方案,我们有$ ProgressPreference。 某些cmdlet仅在通过计时器进行长时间操作时显示进度条。

删除-Ping开关(这是默认行为)。

最佳实践是在脚本中使用显式参数。 它使代码更具可读性。 在仅实施ping的Windows PowerShell cmdlet中,没有必要。 新的cmdlet实现了更多功能,我们需要为每个cmdlet提供新的显式参数。

您的提案是我在第一步中实施的,但由于不适合用于交互式会议而被拒绝。 例如,运行命令Test-Connection www.google.com -TraceRoute后,我们可以在很长一段时间内查看空白屏幕。 因此更改了实现以显示每个响应的输出(字符串或进度条)。

拆分对象格式不需要显示进度,因为在将每个对象提交给输出时,我们可以很容易地看到进度。 这里唯一需要它的原因是因为我们不会像其他所有PowerShell cmdlet一样在检索数据时将数据输出到管道。 如果我们在每个PingReply-TraceRoute跟踪跳上输出,则_have_进度显示将内置在输出显示中。

我上面的建议是引入“交互”开关,以将交互方案和脚本方案分开。 您建议对Verbose开关执行相同的操作,这是更不自然的做法。

-Verbose是一个公共参数,因此与全新开关相比,cmdlet的选择更为自然。 我们不需要在这里重新发明轮子。

最佳实践是在脚本中使用显式参数。 它使代码更具可读性。 在仅实施ping的Windows PowerShell cmdlet中,没有必要。 新的cmdlet实现了更多功能,我们需要为每个cmdlet提供新的显式参数。

我既不在这里,也没有那里,但通常cmdlet的默认行为没有开关。 例如,我们没有-Loud开关作为-Quiet的反向按钮。

拆分对象格式不需要显示进度,因为在将每个对象提交给输出时,我们可以很容易地看到进度。

通过上面的建议,我们将“ ping”对象收集在“ meta”对象中,并且不可能实时输出“ ping”对象-我们只能在管道中输出“ meta”对象-用户将始终看到空白显示。

-Verbose是一个常用参数,因此,与全新的开关相比,cmdlet的选择更为自然。

我不知道有任何cmdlet将大量信息输出到详细信息流。 我们始终使用此流来显示其他诊断信息,以便我们了解运行cmdlet的过程。

通常,cmdlet的默认行为没有开关。

适用于单个参数集。 现在我们有许多参数集,我们需要显式地指定每个参数集。

通过上面的建议,我们将“ ping”对象收集在“ meta”对象中,并且不可能实时输出“ ping”对象-我们只能在管道中输出“ meta”对象-用户将始终看到空白显示。

元对象是不必要的。 如以上建议中所述,将为_each_ PingReply或跟踪跃点创建并输出对象。 模拟并不是最终的代码,仅仅是一种易于复制的格式来说明这一想法。 表中的每个条目将被一个一个输出。 请阅读完整的建议。

我不知道有任何cmdlet将大量信息输出到详细信息流。 我们始终使用此流来显示其他诊断信息,以便我们了解运行cmdlet的过程。

我也不知道_any_ cmdlet通常向信息/主机输出“重要的”信息,并且除了将数个层次埋在另一个对象中之外不输出。

适用于单个参数集。 现在我们有许多参数集,我们需要显式地指定每个参数集。

我认为这样做没有太大用处,但我认为不会造成很大的伤害。 我只是觉得这很浪费时间。 我不确定许多人会在为默认行为指定开关时看到很多用处。

元对象是不必要的。

_这是至关重要的。
这种方法使cmdlet变得毫无用处。 如果您的网络存在问题,请尝试使用该cmdlet运行诊断。 你不能做这个。 您将抛出它并使用ping和traceroute实用程序。 但是现在您可以在控制台中,例如在脚本中的监视系统中,使用新cmdlet进行相同的诊断。 我了解,如果您不定期进行网络诊断,将很难理解。 查看这些本机实用程序有多少个参数,尤其是在Unix版本中。 所有这些对诊断都很重要。 诊断的艺术在于使用它们的组合和神奇的含义。 我试图将所有这些添加到新的cmdlet中。

我只是觉得这很浪费时间

使用位置参数可以帮助您:-)

PowerShell委员会的简短摘要。

当前的cmdlet已设计

  • 获取适用于所有受支持平台的便携式cmdlet。 确实,.Net Core中仍然存在一些问题,因此,并非所有功能都适用于Unix计划格式
  • 获得流行工具的功能,如ping,traceroute,路径,Portqry.exe等
  • 在__scripts__中获得有用的输出对象,适用于简单和深入的网络可访问性分析
  • 使用_header_和_footer_获得有用的控制台输出。 请注意,在某些情况下,该cmdlet显示的信息甚至比原生prototope实用程序还要有用。
  • 以便将来进行诸如远程测试“ Test-Connection -Source ... -Destination ...”的改进

主要问题是如何组合交互式控制台输出(交互式方案)和管道中对象的输出(脚本方案)。 我目前的建议是使用参数(-Interactive)或使用新的cmdlet(用于交互式脚本的Show-Connectivity和用于脚本脚本的Test-Connectivity)进行拆分。
另外我建议将cmdlet的名称更改为Test -__ Connectivity__,这更准确。 它还将允许通过代理(WCM)免费使用旧的Windows cmdlet,而不会造成名称冲突。

@iSazonov您能提供一个这样的诊断示例,该诊断需要一个将所有数据隐藏起来的元对象吗? 我的建议是将信息从元对象移到每个PingReply对象中。 我看不到如何减少cmdlet的实用程序。

如果创建后立即输出对象,如何将统计信息从页脚放到第一个“ ping”对象?

什么页脚信息? ping的唯一页脚信息是Ping complete.

我在任何地方都可以看到当前元对象中的统计信息; 它们只是包含所有具有相同信息的对象,这些对象将以较少使用的格式在信息流上呈现为字符串数据。

这里的要点是使两个版本(WinPS和Pwsh)上的cmdlet(在这种情况下均为Test-Connection)保持相同的方式,在此情况下向cmdlet添加一个开关以“禁用”该输出将是错误的,因为就像我所说的那样这意味着使用该cmdlet的每个脚本/模块都必须进行更新之前,解决方案在两个版本上均采用相同的方法

@ NJ-Dude Windows cmdlet基于WMI,因此无法向后兼容移植。 5.1也已冻结-以后将不再添加。

@ NJ-Dude Windows cmdlet基于WMI,因此无法向后兼容移植。 5.1也已冻结-以后将不再添加。

我了解并知道,我只是说语法和功能应该相同,这意味着,如果使用QUIET不会显示任何输出,那么无论所用PS的风格如何,它都不应显示任何输出。

我只是说SYNTAX和功能应该相同

是不可能的。 Windows兼容性模块是获取旧功能的单一方法。

cmdlet的输出应该能够存储和使用,而不必手动抑制不需要的显示到控制台的显示,该显示在某种程度上与主输出是分开的。

没有其他cmdlet_会以这种方式运行,其中最有用的数据是信息流上的字符串形式。 没有任何理由使其表现为这种方式。 所有数据应在输出流period上。 根据需要,其他数据位于详细或调试流中。 对于PowerShell本身附带的cmdlet,以这种方式使用信息流实际上是前所未有的。

如前所述,您提到的页脚中没有任何数据需要专门放在页脚中; 从一开始就可以使用,也可以在处理每个响应时使用。

排队进行委员会讨论

太糟糕了,我在这里没有对线程进行跟踪,在杂草中遇到了麻烦,但是我不考虑实现的基本看法是:

  • 数据应逐行输出。 我认为这就是Test-Connection s和ping.exe等的当前情况
  • 数据应作为结构化对象返回。 格式应该与这个事实无关。 (尽管这很可怕,但我看到一个格式化程序向控制台发出了JSON字符串,尽管它实际上是一个PSObject。我的意思就是可以做到这一点。)格式化也是我们可以使用的地方允许更改我们想要的任何内容而不会中断更改。 (也非常赞同@ vexx32 ,我们应该谨慎对待与属性名称不匹配的列标题。出于可读性的考虑,有时这是必需的,但这也会使我发疯。)
  • 像Windows PowerShell一样, -Quiet除了布尔值True / False外,什么都不会发出。
  • 如果比默认情况(比最小布尔值-Quiet情况要多),我们需要发出的信息更多,则-Verbose听起来很合理,但是我还没有足够的考虑。 (这也是我失去主线的地方,很难说出上面更多的人想要的东西)。
  • 模仿具有与Windows PowerShell相同的属性的完全相同的对象( cimv2\Win32_PingStatus )是不可能的(因为.NET Core,WMI等),但是我们应该尝试使其尽可能接近。
  • 我不知道进度。 我的高阶观点是,进展缓慢(尽管我们进行了优化)仍然使每个人都发疯(尽管我们进行了优化),而且在非交互性中也没关系,因为每个人都在设置$ProgressPreference

听起来不错!

进步主要使我烦恼,因为它无法在命令调用中处理; 您必须设置$ ProgressPreference。 我真的希望这是一个常用参数。...但是我还有另一个问题要解决,所以我们不要在这里讨论! :微笑:

@ PowerShell / powershell-committee对此进行了审查。 我们同意Test-Connection应该尽可能模仿Windows PowerShell 5.1中的行为(包括-Quiet )。 这意味着,对于具有默认格式的属性以及可用的任何其他属性的每个答复,都应发出PingStatus输出对象(除去win32_ )。 不应使用进度。

有人愿意编写显示cmdlet语法以及建议的输出格式的简短RFC进行审查吗?

@ stevel-msft我很高兴。 :)

我喜欢这样的声音。
谢谢

Kinda有趣的是,PR 3125涵盖了所有这些内容,但是Test-Connection的使用被拒绝了,但是现在我们已经全面发展了。 回顾3125怎么样?

简要地看一下它,看起来它实际上是用Unix平台上的另一种不同的命令替代了Test-Connection来尝试模仿Windows命令吗? 我读对了吗?

我认为这不是我们可用的最佳选择。 整个平台在执行整个命令方面的一致性更有价值。 我敢肯定,它可能有一些有趣的想法我们可以利用。

完成编写后,我将删除指向RFC草案的链接,并随时评论,调整等。我很乐意听到对此的更多观点。 🙂

编辑: https

我针对此问题的具体用例是基于在Linux上使用PowerShell Core的愿望,但是该实现已在Windows和Linux上进行了全面测试。 它的目的是完全替换丢失的命令。

我们什么时候会看到这个? 在6.2.2中? 那可能什么时候降落?
(很高兴看到这个线程从2018年4月开始肆虐,直到现在变得安静。

我认为我可以很容易地编写此代码,我只是在等待RFC被接受。 很快,我会完成它并为此提交PR。 :微笑:

哦,我认为状态是已批准(不知道确切的状态或完整的过程是什么)。 但是感谢您的更新。 仍然很可惜,它花了12个月才变得安静:)

超过12个月使它安静

我希望有更多反馈

@ vexx32,您可以开始对此进行编码,并将其放在“实验”标志后面,以防万一有任何反馈意见改变了当前提案

@ SteveL-MSFT我已经有了一个可以正常工作的实现。 我希望尽快提交带有一些实验性标志的PR,以便我们可以更具体地讨论代码。 💖

在最后几天考虑了所需的行为后,我希望默认情况下具有最少参数(快速键入和用户友好的显示)的交互式行为,这在交互式会话中会很方便。 并转换为带有其他参数的脚本样式(这意味着输出中的类型不同)。

您能否详细说明一下@isazonov的工作方式?

@ vexx32您是否询问实现或UX设计?

我认为,主要是您认为UX的原因。 :)

在交互式会话中,最佳UX是
1.最少打字
它的意思是:
-默认为ping
-使用一个参数切换到另一种模式(traceroute等)
2.人性化的输出
它的意思是:
-像我在演示代码中尝试的那样,在控制台host_上模拟ping.exe(tracert.exe等)的输出-标题,页脚和信息行格式正确。 无需考虑输出类型-不使用它们,仅显示它们。
-添加参数以切换到脚本模式-即禁止在控制台主机上输出用户友好的文本并发出强类型的对象。 无需格式化此输出。 我们讨论了Quiet,它返回True / False,但是我们需要一个参数来发出其他原始强类型对象(如-RawOutput)。 在脚本中使用其他参数是可以接受的UX。

谢谢,我想我知道您现在的情况会好一些。

不过,我真的看不到需要这种双重模式吗? PowerShell中没有其他cmdlet在交互式和“脚本模式”参数之间进行此拆分。

如果您想要ping / tracert的确切输出,为什么不直接使用这些实用程序呢?

PowerShell从未做出过很大的努力来完全模仿现有命令。 我认为Get-ChildItem可能是最接近的,但几乎是唯一这样做的。

如果我们想像您所说的那样完全模拟ping / tracert显示,我建议我们将其作为单独的cmdlet或函数,例如Show-Connection ,而不要使Show-Command杂乱无章,没有多余的参数PowerShell中的先例或需求。

不过,我真的看不到需要这种双重模式吗? PowerShell中没有其他cmdlet在交互式和“脚本模式”参数之间进行此拆分。

我们在格式化系统方面存在差距。 例如,我们在请求具有页眉/页脚目录时遇到问题。 在其他情况下也很方便。

如果您想要ping / tracert的确切输出,为什么不直接使用这些实用程序呢?

我做 :-)。 这些本机实用程序非常强大,因为它们是底层的,但它们是冻结的。 我们可以做比它们更聪明的事情-这是此cmdlet外观的本质(而不仅仅是进行ping操作)-如果您深入了解cmdlet中的地址和名称是如何形成的以及它们如何形成的输出后,您会发现比本地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 等级

相关问题

lzybkr picture lzybkr  ·  3评论

rudolfvesely picture rudolfvesely  ·  3评论

manofspirit picture manofspirit  ·  3评论

JohnLBevan picture JohnLBevan  ·  3评论

aragula12 picture aragula12  ·  3评论