Related: #4715 and #4626.
Currently, it is not easy to discover which of a given cmdlet's / advanced function's parameters accept pipeline input and how (by value and/or by property name):
Using the example of Rename-Item:
You can use Get-Help Rename-Item -Full and then browse the entire topic for Accept pipeline input? lines
You can use a nontrivial command such as the following:
Get-Help Rename-Item -Parameter * | ? pipelineInput -like 'true*' | Select-Object Name, Type, pipelineInput
The above yields:
name type pipelineInput
---- ---- -------------
Credential @{name=PSCredential; uri=} true (ByPropertyName)
LiteralPath @{name=String; uri=} true (ByPropertyName)
NewName @{name=String; uri=} true (ByPropertyName)
Path @{name=String; uri=} true (ByValue, ByPropertyName)
Neither option is convenient.
Perhaps the syntax diagrams could be enhanced with symbols that reflect pipeline-binding behavior?
Something along the lines of (these are mere examples; the idea is to be concise):
| ... by value (only)⌠... by property name (only)|⌠... by both value and property nameApplied to the Rename-Item example, with the symbols placed inside (...) after the parameter (for example):
Rename-Item [-Path(|⌠)] <String> [-NewName] <String> [-Credential(⌠) <PSCredential>] [-Force] [-PassThru] [-Confirm] [-WhatIf] [-UseTransaction <SwitchParameter>]
[<CommonParameters>]
Rename-Item [-NewName(⌠)] <String> [-Credential(⌠) <PSCredential>] [-Force] [-PassThru] -LiteralPath(⌠) <String> [-Confirm] [-WhatIf] [-UseTransaction <SwitchParameter>]
[<CommonParameters>]
Note: A crucial piece missing from the above is that parameters have _aliases_ and that binding by property name often happens via those aliases; e.g., Select-String's -LiteralPath has an alias of PSPath, and when you pipe Get-ChildItem output to Select-String, the objects bind by .PSPath, not .LiteralPath.
Written as of PowerShell Core v6.0.0-beta.3.
I like the intent, not sure if I like the proposed syntax, but don't have an alternative off the top of my head
@SteveL-MSFT: Glad to hear it; I'm not too thrilled with the specific syntax myself, but I wanted to get the conversation started.
This is somewhat orthogonal to the Get-Command -Syntax request but a number of us PS users, rely on a command called Get-Parameter to get this info. It comes with the PSCX module. Here's the output from this command for Rename-Item:
PS C:\> Get-Parameter Rename-Item
Command: Microsoft.PowerShell.Management/Rename-Item
Set: ByPath *
Name Aliases Position Mandatory Pipeline ByName Provider Type
---- ------- -------- --------- -------- ------ -------- ----
Confirm {cf} Named False False False All SwitchParameter
Credential {Cr*} Named False False True All PSCredential
Force {F*} Named False False False All SwitchParameter
NewName {N*} 1 True False True All String
PassThru {Pas*} Named False False False All SwitchParameter
Path {Pat*} 0 True True True All String
UseTransaction {usetx} Named False False False All SwitchParameter
WhatIf {wi} Named False False False All SwitchParameter
Command: Microsoft.PowerShell.Management/Rename-Item
Set: ByLiteralPath
Name Aliases Position Mandatory Pipeline ByName Provider Type
---- ------- -------- --------- -------- ------ -------- ----
Confirm {cf} Named False False False All SwitchParameter
Credential {Cr*} Named False False True All PSCredential
Force {F*} Named False False False All SwitchParameter
LiteralPath {PSPath, L*} Named True False True All String
NewName {N*} 1 True False True All String
PassThru {Pas*} Named False False False All SwitchParameter
UseTransaction {usetx} Named False False False All SwitchParameter
WhatIf {wi} Named False False False All SwitchParameter
Personally, I find this far easier to parse than the output of Get-Command -Syntax.
@rkeithhill:
That's indeed a very nice representation, and perhaps integrating it via a different parameter, such as -ExtendedSyntax, is the solution (as opposed to cramming more information into the existing diagrams - though the two aren't mutually exclusive).
Incidentally, shouldn't Get-Help have a -Syntax parameter too? I was looking for it, not remembering that it exists for Get-Command only.
(As an aside: I can install the PSCX module on macOS, but it won't load (Could not load file or assembly 'Pscx.Core, Version=3.2.6024.39574, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.)).
PSCX has not been ported to .NET Core yet. It's on the backlog which just got a bit shorter with the Unicode esc seq PR going through. :-) I've also been waiting on .NET 2.0 to stabilize along with the required PS SDK for portable module development. I got a bit burned by hopping on ASP.NET Core way too soon (alpha days) and almost every new build broke my code.
Thanks for letting me know; allow me to continue the tangent: on Windows, I get a warning about howExpand-Archive,Get-Hash,prompt,Format-Hex,Get-Help,Get-Uptime would be shadowed - any plans to not shadow built-in cmdlets, or is there a way to load only those commands that don't shadow built-in ones?
Yes. This has been a continual issue (and a good one to have) with PSCX because we've introduced commands that over time have made their way into PowerShell (yay!).
As for loading module specific commands you can always module-prefix a command e.g. Microsoft.PowerShell.Archive\Expand-Archive.
Prefixing the command doesn't help if another module uses it and didn't prefix it themselves. You could use Import-Module -Prefix "CX" -Name PSCX to explicitly load PSCX with a custom prefix, though that would not be good for code re-use.
What I do is modify the PSD1 file in the module directory to comment it out from CmdletsToExport. However, it would be lost in an upgrade and need to be redone if that command is still there.
I should have more correctly stated that the example was using a module qualified name which is different from (user and module specified) prefixing. Module qualified names should always work because PowerShell will not let you load two different modules with the same name. Regardless, this thread is straying pretty far from the original issue.
To get back on track: I realized that just marking the parameters by their declared names may not be enough, given that binding often happens via _aliases_, so a more verbose presentation that includes aliases - such as the PSCX Get-Parameter cmdlet's - is definitely (also) needed.
Most helpful comment
This is somewhat orthogonal to the
Get-Command -Syntaxrequest but a number of us PS users, rely on a command calledGet-Parameterto get this info. It comes with the PSCX module. Here's the output from this command forRename-Item:Personally, I find this far easier to parse than the output of
Get-Command -Syntax.