当命令行开关接受管道输入时,ByPropertyName和ByValue之间有什么区别?

时间:2014-01-14 15:58:23

标签: powershell powershell-v3.0

一些PowerShell命令行开关接受管道输入ByProperyName,有些人接受ByValue,其他人则为两者做。这是什么意思?它如何影响我们的PowerShell脚本?

2 个答案:

答案 0 :(得分:7)

ValueFromPipeline parameter attribute会将参数值映射到从管道传入的任何对象类型。如果使用ValueFromPipelineByPropertyName parameter attribute,则将使用通过管道输入命令+参数的对象使用特定属性。

ValueFromPipeline示例

Get-Process | Stop-Process; # Stop-Process expects to receive a Process object

<#
 -InputObject <Process[]>
    Stops the processes represented by the specified process objects. Enter a variable that contains the objects, or
    type a command or expression that gets the objects.

    Required?                    true
    Position?                    1
    Default value
    Accept pipeline input?       true (ByValue)
    Accept wildcard characters?  false
#>

ValueFromPipelineByPropertyName示例

# Get-Process looks for a ComputerName property on the incoming objects
[PSCustomObject]@{
    ComputerName = 'localhost';
    } | Get-Process;

<#
-ComputerName <String[]>
    Gets the processes running on the specified computers. The default is the local computer.

    Type the NetBIOS name, an IP address, or a fully qualified domain name of one or more computers. To specify the
    local computer, type the computer name, a dot (.), or "localhost".

    This parameter does not rely on Windows PowerShell remoting. You can use the ComputerName parameter of Get-Process
    even if your computer is not configured to run remote commands.

    Required?                    false
    Position?                    named
    Default value                Local computer
    Accept pipeline input?       True (ByPropertyName)
    Accept wildcard characters?  false
#>

答案 1 :(得分:3)

概述

PowerShell命令行开关返回对象并接受对象作为参数。对象始终是一个特定类型,并且具有许多属性。

,例如,Get-Service命令行开关返回一个System.ServiceProcess.ServiceController对象,该对象具有Name,RequiredServices,CanPauseAndContinue和DisplayName等属性。

当我们将一个对象跨越管道传递给另一个命令行开关时,第二个命令行开关匹配对象的TypeName(ByValue)或匹配对象的一个​​PropertyNames。

接受管道输入ByValue

在这种情况下,第一个命令行开关的 TypeName 必须与第二个命令行开关的参数类型相同。

实施例

Get-Service TypeName 是ServiceController,Stop-Service命令行开关有一个名为InputObject的ByValue参数参数类型 ServiceController。

这是有效的,因为System.ServiceProcess.ServiceController与sa ServiceController []的类型相同。换句话说,它们匹配ByValue。这是证据。

C:\> get-service | get-member | select typename -first 1

TypeName
--------
System.ServiceProcess.ServiceController

C:\> get-help stop-service

-InputObject <ServiceController[]>

    Accept pipeline input?       true (ByValue)

接受管道输入ByPropertyName

在这种情况下,第一个命令行开关的类型必须具有属性名称,它与第二个命令行开关的参数名称相同。

实施例

ServiceController类具有名为Name的属性,Stop-Service命令行开关具有名为name的ByPropertyName参数。因此,它们匹配ByPropertyName。这是证据:

C:\> get-service | gm | where MemberType -like "*property" | select Name

Name
----
Name
RequiredServices
CanPauseAndContinue
CanShutdown
CanStop
Container
DependentServices
DisplayName
MachineName
ServiceHandle
ServiceName
ServicesDependedOn
ServiceType
Site
Status

C:\> get-help stop-service    -Name <String[]>

    Accept pipeline input?       true (ByPropertyName, ByValue)

这让人很难理解。对我来说,记住ByValue确实意味着ByTypeName会有所帮助。