Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit of 32 parameter sets #9372

Open
MiYanni opened this issue Apr 15, 2019 · 5 comments

Comments

Projects
None yet
4 participants
@MiYanni
Copy link

commented Apr 15, 2019

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.

@lzybkr

This comment has been minimized.

Copy link
Member

commented Apr 15, 2019

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.

@MiYanni

This comment has been minimized.

Copy link
Author

commented Apr 16, 2019

@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.

@lzybkr

This comment has been minimized.

Copy link
Member

commented Apr 16, 2019

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.

@vexx32

This comment has been minimized.

Copy link
Contributor

commented Apr 16, 2019

😬 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.

@MiYanni

This comment has been minimized.

Copy link
Author

commented Apr 19, 2019

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.