Skip to content

PSShouldProcess rule is getting *worse* instead of better. #644

Closed
@Jaykul

Description

@Jaykul

Consider the following code:

function Invoke-TSKill {
    [CmdletBinding()]
    param()
    if ($PSCmdlet.ShouldProcess("Stop MyProcess")) {
       TSKill "MyProcess"
    }
}

function Invoke-StopMyProcess {
    [CmdletBinding(SupportsShouldProcess)]
    param()

    Invoke-TSKill
}


function Stop-MyProcess {
    [CmdletBinding(SupportsShouldProcess=$false)]
    param()
    Invoke-StopMyProcess
}

ScriptAnalyzer output

RuleName                            Severity     FileName   Line  Message
--------                            --------     --------   ----  -------
PSShouldProcess                     Warning                 18    'Stop-MyProcess' calls ShouldProcess/ShouldContinue but
                                                                  does not have the ShouldProcess attribute.
PSUseShouldProcessForStateChangingF Warning                 18    Function ’Stop-MyProcess’ has verb that could change system
unctions                                                          state. Therefore, the function has to support
                                                                  'ShouldProcess'.

The intent of #608 and #521 was that you should not throw an error when a function chooses to support ShouldProcess in order to pass the ConfirmPreference through to another function.

As of 1.8.1, this is indeed fixed, and PSScriptAnalyzer does not warn about Invoke-StopMyProcess. Congratulations?

You've gone too far...

1. Why is there no warning on Invoke-TSKill?

Obviously this function needs to have SupportsShouldProcess on it, because it actually does call ShouldPocess without having SupportsShouldProcess on the CmdletBinding attribute.

2. Why does the warning refer to a "ShouldProcess attribute"?

'Stop-MyProcess' calls ShouldProcess/ShouldContinue but does not have the ShouldProcess attribute.

The fix is to add SupportsShouldProcess to the [CmdletBinding()] attribute. This is just confusing.

3. Why am I getting a warning about Stop-MyProcess at all?

The warning claims that I'm calling ShouldProcess or ShouldContinue, but I am not. This simple repro case is easy to follow, but in the real world, this warning happens on scripts with hundreds of lines of code and the actual ShouldProcess is probably happening in one of the functions I call, but I don't know which. Since you know which, you should say which.

Frankly, I should never be forced to pass thru SupportsShouldProcess at all -- there's no reason why I must pass the ShouldProcess support up through my function. This warning should be informational when it's talking about a recursive implementation.

There are lots of reasons why it might not be desirable to passthru.

Additionally, I've explicitly stated that I do not support it. The error does not notice that I've already added the parameter with $false

4. You are still using the verb as an excuse to tell me I nee ShouldProcess

It's ridiculous that I'm getting an extra warning for Stop-MyProcess just because it uses Stop. We've discussed this before #283

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions