PSScriptAnalyzer: PSReviewUnusedParameter has false positive when using $MyInvocation.BoundParameters

Steps to reproduce

There may be some rare cases where we would be using ParameterSetName instead of ParameterName, for example

$sb = {
        function Test-PSReviewUnusedParameter {
        <#
        #>
        [CmdletBinding()]
        Param(
            [Parameter(ParameterSetName = 'Foo')]
            [switch]
            $FooBar
        )

        try{
            if ($PSCmdlet.ParameterSetName -eq 'Foo') {
                # I am doing something
            }
        } catch {
            throw
        }
    }
}

# Invoke-ScriptAnalyzer -ScriptDefinition [scriptblock]$sb

RuleName                            Severity     ScriptName Line  Message
--------                            --------     ---------- ----  -------
PSReviewUnusedParameter             Warning                 9     The parameter 'FooBar' has been declared but not used.

Expected behavior

I expect this to be not flagged

Actual behavior

Flags it as violation

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      5.1.18362.752
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.18362.752
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

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

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 18 (11 by maintainers)

Most upvoted comments

I have the changes ready, waiting for my firm to approve my OSS contribution.

Cool, Thanks. I will submit a PR. Thanks @bergmeister

do another search on scriptBlockAst to get the VariableExpressionAst of MyInvocation out again and do a recursive .FindAll search on it to get its child element of type StringConstantExpressionAst out and check if it is BoundParameters.

I am afraid whether that would work. BoundParameters is not a child element of MyInvocation (VariableExpressionAst). Its a member of andMemberExpressionAst, where the expression is VariableExpressionAst. Both of them are child elements of MemberExpressionAst. Can you tell me if I am missing anything here ? Also Show-Ast is really useful.

Yh, you’re right, it looked like a child to me first but is actually at the same level as VariableExpressionAst. I guess the best is to then search for VariableExpressionAst, get the parent MemberExpressionAst by using the .Parent property and from that element do something like a .FindAll(oneAst -> oneAst is StringConstantExpressionAst, searchNestedScriptBlocks: false) search to get the StringConstantExpressionAst that you could then check for the BoundParameters property. That’s just a rough idea that should get you there. Have a look at the properties and methods of the individual Ast implementations (Intellisense or docs) that can sometimes be helpful in the AST search as well.

Just look at the line that I linked before: https://github.com/PowerShell/PSScriptAnalyzer/blob/master/Rules/ReviewUnusedParameter.cs#L49 You could do a check if variableCount contains MyInvocation and if so, do another search on scriptBlockAst to get the VariableExpressionAst of MyInvocation out again and do a recursive .FindAll search on it to get its child element of type StringConstantExpressionAst out and check if it is BoundParameters. The readme has instructions on local development setup here or alternatively you can just use Visual Studio Codespaces or the remote Containers feature in VS-Code that will set everything up to work out of the box. Once you’re setup, just call ./build.ps1 and the built module will be in a local folder called out. Familiarity with C# development and AST is assumed, the ShowPSAst is quite useful to visualize the PowerShell AST. At the start of June, I will give a talk at the online and free PSConfEU 2020 where I will demo how to build/debug PSSA as well and you will be able to watch that video on-demand: https://powershell.one/psconfeu/psconf.eu-2020/about