question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Make it more obvious when cmdlet parameters are flag-based enumeration types

See original GitHub issue

Summary of the new feature/enhancement

  • Parameters that are flag-based enumeration types (e.g., System.Management.Automation.ScopedItemOptions) i.e. types that allow combining values (bit-ORing) them implicitly accept an array of values, courtesy of PowerShell’s flexible type conversions.

  • However, this fact isn’t an obvious from the syntax diagrams; in effect you need to know the specifics of the parameter types in order to infer whether multiple values are accepted:

    • Purely on a formal level, the fact that the parameter type is a scalar (e.g. ScopedItemOptions) rather than an array (e.g., ScopedItemOptions[]) provides no indication - which is what you see with Get-Command -Syntax
    • Those cmdlets that provide MAML based help may explicitly list the individual enum values, but again there is nothing that indicates that combinations are allowed (and from the values themselves that cannot necessarily inferred).
    • If the parameter name is a singular (e.g., New-Variable -Option) rather than a plural (e.g., Get-ChildItem -Attributes), it too doesn’t provide any clues.

Using the example of New-Variable with its -Option parameter:

# CURRENT behavior:
PS> Get-Command -Syntax New-Variable
New-Variable ... [-Option <ScopedItemOptions>]

Note the singular name, and the scalar type name, neither of which provide a strong clue that an array of values - e.g., New-Variable foo bar -Option ReadOnly, AllScope can be passed (the plural in the type name does to an extent, but not every flag-based enumeration is guaranteed to have that).

# CURRENT behavior:
PS> Get-Help  New-Variable
...
New-Variable ... [-Option {None | ReadOnly | Constant | Private | AllScope | Unspecified}] ...
...

The listing of all values again provides no clue that multiple values may be passed.

User shouldn’t have to determine the full type name and perform a .NET documentation lookup just to learn when a given enum type is flag-based, i.e. accepts an array of values.

Proposed technical implementation details (optional)

As an aside, re documentation: the parameter descriptions should explicitly mention when a parameter type is a flag-based enumeration, and the examples should ideally comprise at least one command that shows a combination - see https://github.com/MicrosoftDocs/PowerShell-Docs/issues/7357

  • Enhance the syntax diagrams to indicate flag-based enumerations, e.g. with a trailing + (a trailing [] to suggest an array may get too cluttered, given the liberal use of [ and ] in syntax diagrams).

  • Selectively disable this for cmdlets where a flag-based enum is situationally used as a single-value parameter, such as Add-Member -MemberType, as @SeeminglyScience points out, and he proposes using a new attribute, [SingleEnumValue] to decorate such parameters - this should drive both the syntax-diagram representation and should prevent attempts to pass multiple values at the parameter-binder level, and ideally also guide tab-completion behavior - see below.

  • Establish a convention to use the plural in the names of parameters whose type is a flag-based enumeration. [This contravenes established PowerShell practice, as @SeeminglyScience notes; the syntax diagram enhancement should be enough (and, as is already the case, properly named .NET flag enums imply their flag-based nature by a plural in their type name)]

Applied to the examples above:

# WISHFUL THINKING:
PS> Get-Command -Syntax New-Variable
New-Variable ... [-Options <ScopedItemOptions>+]

# WISHFUL THINKING:
PS> Get-Help  New-Variable
...
New-Variable ... [-Options {None | ReadOnly | Constant | Private | AllScope | Unspecified}+] ...
...

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
SeeminglySciencecommented, Mar 18, 2021

I think @iSazonov is trying to ensure someone knows that docs would need to be explicitly regenerated if the syntax diagram were to be changed.

Enhance the syntax diagrams to indicate flag-based enumerations, e.g. with a trailing + (a trailing [] to suggest an array may get too cluttered, given the liberal use of [ and ] in syntax diagrams).

I think that’s probably the way to do it. Though not all parameters typed as flag enums will actually accept multiple values, like Add-Member -MemberType. Maybe a additional attribute like SingleEnumValue to disable that conditionally.

Establish a convention to use the plural in the names of parameters whose type is a flag-based enumeration.

This would be counter to the typical recommendation of always singular, e.g. Get-ChildItem -Name instead of Names.

1reaction
mklement0commented, Mar 18, 2021

Thanks, @SeeminglyScience.

Good point about Add-Member -MemberType. I’ve added a note to the OP.

The plural issue is tricky, for sure - PowerShell and .NET clash here: PowerShell favors the singular, whereas by convention flag-based enums use plural names (e.g., ScopedItemOptions ). But, given that explicitly array-based parameters have singular names too (e.g., -Path), I agree that it makes sense to stick with PowerShell’s convention - I’ve updated the OP accordingly.

As for coordinating with the docs team to ensure regeneration: good point, but I think it makes sense to wait for this proposal to be green-lighted first.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Enum parameter for powershell cmdlet
I'm writing a cmdlet (script) on powershell and I wanted to use eunm as one of the parameters. But I don't know where...
Read more >
Set-Variable (Microsoft.PowerShell.Utility)
Specifies the value of the Options property of the variable. Valid values are: ... These values are defined as a flag-based enumeration. You...
Read more >
What is a Cmdlet and How Does It Work?
A cmdlet and its relevant parameters can be entered in a PowerShell command line for immediate execution or included as part of a...
Read more >
Best practice to handle a simple enum as parameter?
Hey, while trying to test something I stumbled upon this, consider this simple script for demonstrative purposes: [CmdletBinding()] param( ...
Read more >
PowerShell Coding Standards - Ed-Fi Tech Docs
When the same parameter is used by multiple cmdlets, always use the same parameter type. For example, if the Process parameter is an...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found