1

I'm not sure if I'm confused about how some of Powershell documentation regarding parameters work, or if the documentation has some mistakes.

For example, the docs for get-verb [1] say that for parameter -Group, the cmdlet accepts pipeline input, at position 0. However, in the Inputs section, it says "None". Also, this doesn't work:

"common" | get-verb

Since the docs says that -Group accepts pipeline input at position 0, doesn't that imply that the above code should work?

The docs for foreach-object [2] say that for parameter -InputObject, the position is "named". However, it accepts the -InputObject parameter at position 0.

get-service | foreach {$_.name}

Shouldn't that parameter's doc say Position: 0?

[1] https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-verb?view=powershell-7.3

[2] https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-7.3

1
  • If you are not sure use Format-Table to see properties, it is great at enumerating through objects : get-service | Format-Table. If you have a group property use get-service | foreach-object { $_.Group }. I like doing following for debugging : get-service | foreach-object { $_ | Format-Table } Commented Dec 4, 2022 at 21:49

1 Answer 1

1

Regarding the first question, the docs are in fact showing inaccurate information and GitHub Issue #9522 was raised to correct this.

Looking at Get-Help we see the following:

PS ..\pwsh> Get-Help Get-Verb -Parameter * | Select-Object Name, Position

name  position
----  --------
Group 0
Verb  1

Yet, if we look at the autogenerated param block using ProxyCommand.Create:

[System.Management.Automation.ProxyCommand]::Create((Get-Command Get-Verb))

We can see the following (positions are reversed from what the doc is showing us):

param(
    [Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
    [string[]]
    ${Verb},

    [Parameter(Position=1, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
    [ValidateSet('Common','Communications','Data','Diagnostic','Lifecycle','Other','Security')]
    [string[]]
    ${Group}
)

We can also clearly see that -Verb is actually position 0 trying positional binding and one valid verb:

Get-Verb Add

As for 'common' | Get-Verb not working, it does as long as we're also binding -Verb in the call to the cmdlet, either by value from pipeline by property name or positional binding:

# All verbs in `Common` groups. Works fine.
# Positional Binding on `-Verb` (Position 0)
'common' | Get-Verb *

# `Add` verb in `Common` groups. Also works fine.
# `ValueFromPipelineByPropertyName` on both params
[pscustomobject]@{ Group = 'common'; Verb = 'Add' } | Get-Verb

Regarding the second statement / question:

...However, it accepts the -InputObject parameter at Position 0.

This is incorrect, -InputObject in fact can be bound either from pipeline or named. Also note that this parameter is not intended to be used manually in most cases.

Position 0 is actually the -Process parameter and we can clearly see it by testing this code:

ForEach-Object { $_ } -InputObject 'hello'
Sign up to request clarification or add additional context in comments.

7 Comments

Can you please explain why this works: 'common' | Get-Verb * ; I as read it, that would have tried to bind 'common' at position 0 which, as you demonstrated, is -Verb.
no, position 0 is * in this case. * is bound to -Verb and 'common' is bound by pipeline to -Group
Also, why get-verb 'add' works, but 'add' | get-verb doesn't?
Ok, want to make clear that I meant: The ProxyCommand output says that -Verb param is at position 0, and it accepts pipeline input, and that input type is string[]. The design seems ok to me, but still doesn't work, which is weird.
You can have PowerShell show you how your code or other code like 'common' | Get-Verb and 'common' | Get-Verb * is processed/evaluated in real-time by using the cmdlets Invoke-ScriptAnalyzer and Trace-Command.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.