When a commandlet accepts pipeline input, what is the difference between ByPropertyName and ByValue?

痞子三分冷 提交于 2019-12-07 04:56:15

问题


Some PowerShell commandlets accept pipeline input ByProperyName, some do it ByValue, others do it for both. What does this mean? How does it impact our PowerShell scripts?


回答1:


The ValueFromPipeline parameter attribute will map the parameter value to whatever object type is passed in from the pipeline. If you use the ValueFromPipelineByPropertyName parameter attribute, then a specific property will be used from the objects that are piped into the command+parameter.

ValueFromPipeline Example

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 Example

# 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
#>



回答2:


OverView

PowerShell commandlets return objects and accept objects as parameters. Objects are always of one particular Type and have many Properties.

E.g., the Get-Service commandlet returns a System.ServiceProcess.ServiceController object that has properties including Name, RequiredServices, CanPauseAndContinue, and DisplayName.

When we pass an object across the pipeline to another commandlet, the second commandlet either matches the TypeName (ByValue) of the object or matches one of the object's PropertyNames.

Accept pipeline input ByValue

In this case, the TypeName of the first commandlet must be the same as a Parameter Type of the second commandlet.

Example

The Get-Service TypeName is ServiceController, and the Stop-Service commandlet has a ByValue parameter called InputObject of Parameter Type ServiceController.

This works because System.ServiceProcess.ServiceController is the same type sa ServiceController[]. In other words, they match ByValue. Here's proof.

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)

Accept pipeline input ByPropertyName

In this case, the Type of the first commandlet must have a Property Name that is the same as a Parameter Name of the second commandlet.

Example

The ServiceController class has a property called Name, and the Stop-Service commandlet has a ByPropertyName parameter called name. Thus, they match ByPropertyName. Here's proof:

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)

This is quite confusing to understand.For me it helps to remember that ByValue really means ByTypeName.



来源:https://stackoverflow.com/questions/21117947/when-a-commandlet-accepts-pipeline-input-what-is-the-difference-between-byprope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!