PSScriptAnalyzer icon indicating copy to clipboard operation
PSScriptAnalyzer copied to clipboard

`Invoke-ScriptAnalyzer` parameterset ambiguity

Open liamjpeters opened this issue 4 months ago • 1 comments

Summary

Both the -Path and -ScriptDefinition parameters of Invoke-ScriptAnalyzer are [string] parameters. Both accept ValueFromPipeline and both are declared as Position=0. While they exist in different parameter sets (each with two variants), there is no unique parameter in either set that would allow PowerShell to disambiguate and select the intended parameter set during binding.

As a result, the default parameter set (Path_SuppressedOnly) is always chosen. Any string passed down the pipeline (by value) or as a positional argument is bound to the Path parameter. This means that ScriptDefinition's Position=0 and pipeline (by value) binding declarations are effectively unreachable - any positional or pipeline string will always be bound to Path.

This isn't a bug, but is a design issue: the ScriptDefinition parameter advertises pipeline (by value) and positional binding, but there is no way for users to actually use these features due to parameter set ambiguity.

I propose removing ValueFromPipeline = true and Position = 0 from ScriptDefinition. This isn't a breaking change as they can't currently be used.

ValueFromPipelineByPropertyName is fine - the below works:

[PSCustomObject]@{ScriptDefinition = '$Var = 1'} | Invoke-ScriptAnalyzer

Environment data

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.4.11
PSEdition                      Core
GitCommitId                    7.4.11
OS                             Microsoft Windows 10.0.22631
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

> (Get-Module -ListAvailable PSScriptAnalyzer).Version | ForEach-Object { $_.ToString() }

1.24.0

liamjpeters avatar Sep 03 '25 16:09 liamjpeters

Further to this... When using the -IncludeSuppressed switch along with either positional or pipeline string input, you get a parameter set resolution error.

"Test" | Invoke-ScriptAnalyzer -IncludeSuppressed

# or

Invoke-ScriptAnalyzer "Test" -IncludeSuppressed
Invoke-ScriptAnalyzer: Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.

liamjpeters avatar Sep 09 '25 16:09 liamjpeters