Powershell参数按属性名和按值绑定

icomxhvb  于 2023-01-02  发布在  Shell
关注(0)|答案(3)|浏览(159)

我想停止名为"ALG"的服务,因此我使用:第一个月
它起作用了。
Get-help stop-service -parameter name表示:
Pipeline input:true(ByPropertyName, ByValue)并且"alg"是"按属性值"对吗?
我想停止一个名为notepad的进程,所以我使用:"notepad" | stop-process,然后我得到一个错误。
Get-help stop-process -parameter name
表示:Pipeline input true(ByPropertyName),而"记事本"是"按属性名称"?
为什么会出现这种错误?

isr3a4wc

isr3a4wc1#

如果要将对象的值绑定到参数 *(按属性名称 *),请执行以下操作之一:
1.传递具有适当命名属性的对象:

[pscustomobject]@{Name='notepad'} |Stop-Process
# or, for older versions of powershell:
'notepad' |Select @{Name='Name';Expression={$_}} |Stop-Process

1.将管道表达式显式绑定到命名参数:

'notepad' |Stop-Process -Name {$_}
2ledvvac

2ledvvac2#

  • Mathias R. Jessen's答案为将 * 字符串 *(进程名称)传输到Stop-Process提供了 * 解决方案 *。
  • js2010's answer对 * 为什么将字符串管道传输到Stop-Process不起作用 * 有正确的 * 解释 *(不需要额外的工作),并且还提供了一种跟踪参数绑定的有用技术,但是--截至本文撰写之时--答案包含了一些附带的信息,使问题有点混乱。

让我作更详细的解释:

    • Stop-Process**,与Stop-Service不同,*的设计 * 不 * 接受 * 字符串 (进程名称)作为管道输入。

虽然字符串输入 * 在抽象意义上 * 仍然可以工作,也就是说,如果字符串可以自动 * 转换 * 为命令的ByValue(整个对象)管道绑定参数所期望的数据类型之一,但Stop-Process * 不是 * 这种情况,因为进程 * 名称 *(字符串)不能(自动)转换为System.Diagnostics.Process示例(-InputObject)[1]。

  • 当PowerShell考虑在调用期间将管道输入绑定到参数-Name时,它会查找具有Name属性*的对象 *,因为参数声明指定 * 仅当输入对象 * 具有为参数 * 命名的属性时 * 才接受管道输入:
  • 在帮助主题(如Stop-Process的帮助主题)中,该值表示为**ByPropertyName**。
  • 在代码中,它表示为System.Management.Automation.ParameterAttribute类型的布尔**ValueFromPipelineByPropertyName**属性;也就是说,用PowerShell代码表示,参数声明类似于:请注意,ValueFromPipelineByPropertyNameValueFromPipelineByPropertyName = $true的缩写

[Parameter(ValueFromPipelineByPropertyName)] [string[]] $Name

  • 一个[string]System.String)示例,比如"alg",没有Name属性--它本身就是名称。
  • 因此,如果没有将唯一的ByValue参数-InputObject自动 * 转换 *[1]为System.Diagnostics.Process类型,并且没有ByPropertyValue参数的NameId属性,则调用 * 失败 *,并显示以下错误消息:这实际上告诉您管道输入无效(不能绑定到任何参数):
  • 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参数(也)被声明为接受字符串 * 直接 * 作为输入对象,* 作为整体 *。

  • 在帮助主题(如Stop-Service的帮助主题)中,该值表示为**ByValue**。
  • 在PowerShell代码中,它表示为**ValueFromPipeline**:

[Parameter(ValueFromPipeline)] [string[]] $Name
注:

  • 虽然一个给定的参数可以是 * 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?行;对于 * non *-pipeline-binding参数,您会在第二列看到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的常用转换规则在这里适用,它使用了this answer中讨论的几种技术。在System.Diagnostics.Process的情况下,从字符串转换是不可能的,因为目标类型既没有包含字符串的单参数构造函数,它也没有静态的.Parse()方法。一个快速测试可转换性的方法是尝试一个 * cast *:[System.Diagnostics.Process] 'notepad'失败。相比之下,[System.ServiceProcess.ServiceController] 'alg'可以工作,因为该类型 * 确实 * 有一个接受字符串的单参数构造函数,但请注意,在对Stop-Service(如'alg' | Stop-Service)的调用中的参数绑定 * 期间,此转换 * 不 * 起作用 *-在那里,字符串按原样绑定到ByValue-Name参数。

0pizxfdo

0pizxfdo3#

“stop-service -name”可以通过值(字符串)管道传输,因此它使用该值。Stop-process无法将字符串转换为-inputobject的进程类型,即通过值管道传输。“Stop-process -name”只能通过属性名称传输。
这里有一点细微差别。一个字符串可以被强制为servicecontroller类型,但不能强制为process类型。所以理论上,一个字符串可以作为-inputobject管道传输到stop-service,但不能用于stop-process。“stop-service -inputobject alg”也可以工作,但“stop-process -inputobject notepad”不行。这两个命令之间的不一致可能会让人感到困惑。

[System.ServiceProcess.ServiceController]'alg'

Status   Name               DisplayName
------   ----               -----------
Stopped  alg                Application Layer Gateway Service

[system.diagnostics.process]'notepad'
InvalidArgument: Cannot convert the "notepad" value of type "System.String" to type "System.Diagnostics.Process".

如果您确实想查看绑定:

trace-command parameterbinding {'alg' | stop-service} -pshost
trace-command parameterbinding {'notepad' | stop-process} -pshost

相关问题