PowerShell / PSScriptAnalyzer

Download ScriptAnalyzer from PowerShellGallery
https://www.powershellgallery.com/packages/PSScriptAnalyzer/
MIT License
1.85k stars 373 forks source link

SupportsShouldProcess doesn't care for WhatIfPreference #1892

Open PrzemyslawKlys opened 1 year ago

PrzemyslawKlys commented 1 year ago

Summary of the new feature It seems the SupportShouldProcess rule doesn't always pick up WhatIf being passed to a function later on. It mostly does this for external modules (that do it properly), but not when the functions are within the same module (different files) that I am actually building.

image

Proposed technical implementation details (optional) I guess a prescan should be made and if there are commands with explicit WhatIf calls or WhatIfPreference calls it should treat it as condition to ignore.

bergmeister commented 1 year ago

PowerShell passes WhatIfPreference on automatically (except for splatting with binary cmdlets due https://github.com/PowerShell/PowerShell/issues/4568) so no need to pass like -WhatIf:$WhatIfPreference unless I am not aware of one of the many PowerShell gotchas.

PrzemyslawKlys commented 1 year ago

From my own testing it doesn't work cross-modules (non-binary modules)

image

And even PSScriptAnalyzer doesn't detect ShouldProcess properly (it doesn't show that for binary modules such as AD/GPO and so on.

SydneyhSmith commented 1 year ago

The expectation is that the rule searches the function block for the should process implementation (not checking the cmdlets called within the function), the rule is just used to check the current function so the rule working as expected

PrzemyslawKlys commented 1 year ago

That's not what I am seeing @SydneyhSmith

image


function Test-Me1 {
    [CmdletBinding(SupportsShouldProcess)]
    param(

    )

    Set-ADUser -Identity "CN=Test User,OU=Users,OU=Test,DC=domain,DC=com" -Replace @{description="Test"}

}

function Test-Me2 {
    [CmdletBinding(SupportsShouldProcess)]
    param(

    )

    Set-ADACL -Identity "CN=Test User,OU=Users,OU=Test,DC=domain,DC=com"
}

function Test-Me3 {
    [CmdletBinding(SupportsShouldProcess)]
    param(

    )

    Set-O365Contact -Identity "CN=Test User,OU=Users,OU=Test,DC=domain,DC=com" -WhatIf:$WhatIfPreferece
}

It is aware of functions from other modules supporting WhatIf or not supporting it, or something else is in play. In screenshot above first function is calling native Set-ADUser (Binary) and it doesn't show ShouldProcess is not called (and normally it would work). In the 2nd one it's calling function from non-binary module and it seems to "detect" it properly, but doesn't actually work as shown in example above. 3rd function tries to use WhatIf:$WhatIfPreference (to workaround issue for non-binary modules) and is not detected as something that supports anything mainly because Set-o365Contact is not available (private function).

I believe that even tho something may be working as expected in terms of detection this rules is giving a false positives that can lead to problems of users, and maybe could be improved to make a full detection.