Powershell: -whatif behavior inconsistent, suggesting unification or alignment.

Created on 15 Jun 2017  路  6Comments  路  Source: PowerShell/PowerShell

Dunno if this should be a feature request or a bug, but here goes:

-Whatif behavior should really be stable and consistent, across c# cmdlets, advanced functions, and any other options that emulate cmdlet behavior, as the current state can easily result in "_did I just change this detail across 500 things even though I specified -whatf_?" Currently there appear to be at least three outcomes.

  1. -Whatif is implemented, and runs correctly, zero changes.
  2. -Whatif isn't implemented, and you get an error, zero changes.
  3. -Whatif isn't implemented, and you just changed stuff, including updating your resume.

Steps to reproduce

Remove-ChildItem c:\folderpath -whatif  # Doesn't remove folder, just announces outcome

Get-ChildItem C:\folderpath -whatif         # Isn't implemented, cmdlet produces an error, no changes

function Get-Nuclear{param($target)  Invoke-PotentiallyDangrousStuffHere}
Get-Nuclear -whatif   # Isn't implemented, runs anyway, hopefully you have tested backups.

Expected behavior

-whatif should behave consistently, if -whatif isn't implemented, it should error.

Granted, if someone puts a -whatif parameter in their cmdlet and doesn't build the logic to support it, that's another story all-together, one that can be blamed on that specific author. But as it currently stands, it's a bit of a guessing game, and that's not where it should be.

Up-for-Grabs WG-Engine

Most helpful comment

@jpsnover I think the issue is that if -whatif is specified explicitly, but the cmdlet doesn't implement it, we should consistently error that -whatif isn't implemented. This seems reasonable to me.

All 6 comments

Here is the model I have in my head.

"Cmdlets which have side effects" should implement -WHATIF.
Get-* should not have side effects and therefor should not implement -WHATIF
From there:
1) If a cmdlet has a side effect and doesn't implement -WHATIF, file a bug on that cmdlet.
2) If a cmdlet has -WHATIF and doesn't implement it, file a bug on that cmdlet.

From there I didn't follow your point about what the guessing game was.

Clarification please

"Cmdlets which have side effects" , does it include all cmdlets that can change the state of system?
Example, New-, Set,Invoke-* etc. ?

Or you were refering to any specific ones will "side effect".

@jpsnover I think the issue is that if -whatif is specified explicitly, but the cmdlet doesn't implement it, we should consistently error that -whatif isn't implemented. This seems reasonable to me.

The guessing game is where you use a module or cmdlet and -whatif isn't implemented, and the cmdlet runs anyway, making changes and not throwing an error. That's not the user expectation that running Get-ChildItem -whatif sets up.

Joe User runs Get-ChildItem -whatif, get an error, and presumes from there that -whatif will throw an error if not implemented, making it safe to use. That presumption lives on until they run into an instance where it is not implemented, and they make a breaking change instead of the test they expected to run. I've done this myself and I've seen other go through this pain on a powershell support channel I assist in, and that's what's prompted this issue report.

I agree with the model, but I would add that if -whatif is not implemented, powershell should throw an error consistently, across cmdlets and anything that emulates them, as it does with get-childitem, as opposed to simply running regardless.

EDIT: After chatting this through with some other bright people, I think we discovered the point I that was bugging me:
-WhatIf (_in my view at least_) is supposed to add safety to unsafe cmdlets/functions. In it's current state, it's not doing that anywhere close to reliably. Can powershell be adjusted to look at a cmdlet/advanced function definition, check to see if whatif is defined when it's called, and error if not? I think that would solve a lot of the uncertainty, and any remaining would be owned by the individual cmdlet/function authors.

I have to say I see that last one pretty frequently: people write non "advanced" functions, and then call them with a "common" parameter, not realizing that it's only _mostly_ common -- and mostly common is partly broken...

Can powershell be adjusted to look at a cmdlet/advanced function definition, check to see if whatif is defined when it's called, and error if not?

I think we can check this in a parse time for scripts (we already have "semantic checks" step). But we should support this for binary too - now I don't know how.

Was this page helpful?
0 / 5 - 0 ratings