让我提供更详细的解释:
Stop-Process,与 Stop-Service 不同,不是旨在接受 字符串(进程名称)作为管道输入。
虽然字符串输入 in the abstract 仍然可以工作,即如果字符串可以自动转换为命令的ByValue 所期望的数据类型之一(整个-object) 管道绑定参数,这 不是 Stop-Process 的情况,因为进程 name(字符串)不能(自动)转换为 System.Diagnostics.Process实例 (-InputObject)[1].
-
当 PowerShell 在调用期间考虑将管道输入绑定到参数-Name 时,它会查找具有Name 属性的对象,因为参数声明指定只有在输入对象具有为参数命名的属性时才接受管道输入:
-
在帮助主题中,例如Stop-Process 的主题,这表示为ByPropertyName。
-
在代码中,表示为System.Management.Automation.ParameterAttribute类型的布尔ValueFromPipelineByPropertyName属性;也就是说,用 PowerShell 代码表示,参数声明类似于:注意,ValueFromPipelineByPropertyName 是 ValueFromPipelineByPropertyName = $true 的缩写
[Parameter(ValueFromPipelineByPropertyName)] [string[]] $Name
-
[string] (System.String) 实例(例如 "alg")没有 Name 属性 - 它是本身的名称。
-
因此,在没有自动转换[1] 到唯一ByValue 参数System.Diagnostics.Process 类型的-InputObject 的情况下,并且在缺少Name 和Id 属性的ByPropertyValue 参数,调用 fails 并带有以下错误消息,它实质上告诉您管道输入无效(不能绑定到任何参数):
The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
Stop-Service,相比之下, 被设计为接受字符串输入,因为它的-Name 参数(也)被声明为接受字符串直接 作为输入对象,作为一个整体。
注意:
-
虽然给定的参数可以是 both ByValue 和 ByPropertyValue - 这确实是Stop-Service 的-Name 参数的情况 - 那是'不典型。
-
通常,管道绑定参数被声明为标量而不是数组(例如,Sort-Object、-InputObject <PSObject> 而不是-InputObject <PSObject[]>),这意味着只支持传递多个参数通过管道,而不是通过直接参数 - 有关背景信息,请参阅 GitHub issue #4242。
检查管道绑定参数:
PS> Get-Help Stop-Process -Parameter Name
-Name <String[]>
Specifies the process names of the processes to stop. You can type multiple process names, separated by commas, or use wildcard characters.
Required? true
Position? named
Default value None
Accept pipeline input? True (ByPropertyName)
Accept wildcard characters? true
注意Accept pipeline input? 行;对于 非-管道绑定参数,您会在第二列中看到 False。
PS> Get-Help Stop-Process -Parameter * | Where pipelineInput -like True*
-Id <Int32[]>
Specifies the process IDs of the processes to stop. To specify multiple IDs, use commas to separate the IDs. To find the PID of a process, type
`Get-Process`.
Required? true
Position? 0
Default value None
Accept pipeline input? True (ByPropertyName)
Accept wildcard characters? false
-InputObject <Process[]>
Specifies the process objects to stop. Enter a variable that contains the objects, or type a command or expression that gets the objects.
Required? true
Position? 0
Default value None
Accept pipeline input? True (ByValue)
Accept wildcard characters? false
-Name <String[]>
Specifies the process names of the processes to stop. You can type multiple process names, separated by commas, or use wildcard characters.
Required? true
Position? named
Default value None
Accept pipeline input? True (ByPropertyName)
Accept wildcard characters? false
注意:上述技术从基于 MAML 的帮助文件中收集参数信息,可能伴随给定的 cmdlet(大多数内置 cmdlet 确实带有此类帮助文件)。虽然帮助文件中的信息应该正确地反映了 cmdlet 的实际参数定义并且通常如此,但不能保证。如有疑问,请改用以下技术,直接检查 cmdlet 的实际定义:
# Lists all pipeline-binding parameters defined by the given cmdlet,
# by examining the actual cmdlet definition.
(Get-Command Stop-Process).ParameterSets.Parameters |
Where-Object { $_.ValueFromPipeline -or $_.ValueFromPipelineByPropertyName} |
Select-Object -Unique Name, Aliases, ParameterType, @{
Name = 'Accepts pipeline input'
Expression = {
'True ({0})' -f ($(
if ($_.ValueFromPipeline) { 'ByValue'}
if ($_.ValueFromPipelineByPropertyName) { 'ByPropertyName' }
) -join ', ')
}
} | Sort-Object Name
[1] 除非通过 System.Management.Automation.ArgumentTransformationAttribute 派生属性(不常见)声明参数支持自定义类型转换,否则此处适用 PowerShell 的常用转换规则,该规则采用多种技术,在 @987654329 中讨论@。在System.Diagnostics.Process 的情况下,不可能从字符串转换,因为目标类型既没有具有字符串的单参数构造函数,也没有静态.Parse() 方法。可转换性的快速测试是尝试 cast: [System.Diagnostics.Process] 'notepad' 失败。相比之下,[System.ServiceProcess.ServiceController] 'alg' 有效,因为该类型确实具有a single-parameter constructor that accepts a string,但请注意,此转换不会在参数绑定期间发挥作用 在对 Stop-Service 的调用中,例如 'alg' | Stop-Service - 在那里,字符串按原样绑定到 ByValue -Name 参数。