Powershell: Limit of 32 parameter sets

Created on 15 Apr 2019  路  5Comments  路  Source: PowerShell/PowerShell

Summary

I didn't know to enter this as a bug, a documentation issue, or a feature request. Basically, there is a limit of 32 usable parameter sets. This hard limit is not documented anywhere (from what I could find). There is a blog post about it from 2015 for someone using PowerShell 3.0:
https://www.craig-tolley.co.uk/2015/07/01/maximum-number-of-powershell-parameter-sets-in-function/

The reason is that the maximum number of parameter sets that can be associated with a parameter is 32. It is 32 because a uint (32-bit number) is storing a bitmask of which parameter sets that parameter is part of. In a technical sense, there is allowed up to uint.MaxValue defined parameter sets. However, the parameters themselves can only associate to 32 parameter sets.

The method that allows uint.MaxValue as a mapping index is AddParameterSetToMap. However, the next method below that one, GenerateParameterSetMappingFromMetadata, you can see that it uses ParameterSetFlag as a bitmask to determine which parameter sets a parameter is part of.

Proposals

If this is seen as a bug or feature request, it likely would be fixed if ParameterSetFlag would be used as an actual index into a List of parameter sets. Then, you can define parameter sets up to uint.MaxValue.

If this is seen as a documentation issue, the max parameters sets allowed (being 32) should be documented in the reference document for about_Functions_Advanced_Parameters and in the conceptual document for Cmdlet Parameter Sets.

Area-Maintainers-Documentation Documentation Needed Issue-Enhancement

Most helpful comment

@lzybkr @vexx32 We have worked around having too many parameter sets. Now, we are (generally) < 10 parameter sets for a given cmdlet. Some cmdlets will go above that, but we shouldn't (hopefully) hit the 32 limit. Despite our generator changes, all my points above are still valid about proper documentation and error handling for this limitation.

All 5 comments

I wonder about the usability of a command with 32 parameter sets, but assuming that's not an issue, what about upping the limit to 64? That might be a simple change (by using a ulong instead of uint).

I'm concerned a list might be bad for performance. The parameter binder is already really slow. I don't know the full history, but this bitmask always felt like the only consideration for performance in the original parameter binder code.

@lzybkr I'm currently working on this: https://devblogs.microsoft.com/powershell/cmdlets-via-autorest/

Basically, based on the number of optional parameters exposed by a REST service, we'd need to create a quite large number of parameter sets. Originally, it would be 2x number of parameter sets. So, 5 optional REST parameters would be the limit. Since we are now aware that this limitation exists, we'll adjust our parameter set generation strategy to attempt to reduce that. We need to support PowerShell 5.1 for now, so the fix here won't be useful for our efforts until much later down the road.

The primary concern is making this limitation known. Beyond that blog post (and looking at the code directly), I found no documentation about this. Upping it to 64 would be beneficial in the future, though. If performance is a concern, AFAIK, the parameter set names are unique. So, using them as a key to a Dictionary should be performant.

Additionally, PowerShell should inform the user that they hit that limit when defining a cmdlet. Right now, it overflows and makes it quite confusing when trying to understand the issue. An error here would be preferred so at least the developer making the cmdlet knows the issue.

I agree there should be an error if you hit the limit. I'm guessing it's a breaking change with minimal risk, but maybe some scenarios work despite having too many parameter sets?

Do keep in mind what the help looks like for commands with many parameter sets. Optional parameters turning into 2x parameter sets would probably result in very confusing output from Get-Command -Syntax.

馃槵 I can see the syntax diagrams now, and they are _not_ pretty!

Speaking of, I should get that syntax diagram rework looked at again, see how I can fix that up some, perhaps.

@lzybkr @vexx32 We have worked around having too many parameter sets. Now, we are (generally) < 10 parameter sets for a given cmdlet. Some cmdlets will go above that, but we shouldn't (hopefully) hit the 32 limit. Despite our generator changes, all my points above are still valid about proper documentation and error handling for this limitation.

Was this page helpful?
0 / 5 - 0 ratings