Closed
Labels
Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aResolution-AnsweredThe question is answered.The question is answered.
Description
Steps to reproduce
function TestEnableNetFirewallRule() {
[CmdLetBinding(SupportsShouldProcess=$true)]
param ([string]$DisplayGroup)
Enable-NetFirewallRule -DisplayGroup $DisplayGroup
}
TestEnableNetFirewallRule -DisplayGroup "Remote Desktop" -WhatIfExpected behavior
The firewall rule is not enabled, and the same output as when calling Enable-NetFirewallRule -DisplayGroup "Remote Desktop" -WhatIf:
What if: Enable-NetFirewallRule DisplayName: RemoteDesktop-Shadow-In-TCP
What if: Enable-NetFirewallRule DisplayName: RemoteDesktop-UserMode-In-UDP
What if: Enable-NetFirewallRule DisplayName: RemoteDesktop-UserMode-In-TCP
Actual behavior
No output, and the firewall rule for Remote Desktop is enabled
Environment data
> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.16299.251
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.16299.251
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1Metadata
Metadata
Assignees
Labels
Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aResolution-AnsweredThe question is answered.The question is answered.
Activity
PetSerAl commentedon Apr 4, 2018
$WhatIfPreferencevariable do not cross module boundaries:mklement0 commentedon Apr 4, 2018
To complement PetSerAl's helpful example with additional information:
Enable-NetFirewallRuleis defined in a module and implemented as a (PowerShell) function rather than as a compiled cmdlet.Unfortunately, as PetSerAl's example shows, functions imported from modules do not see (implicitly set) preference variables from the callers's scope (unless that scope happens to be the global one).
In the case at hand, your
TestEnableNetFirewallRulefunction's[CmdLetBinding(SupportsShouldProcess)]attribute causes PowerShell to translate the-WhatIfswitch into a local$WhatIfPreferencevariable with (effective) value$True(it is technically a[switch]instance whose.IsPresentproperty reports$Trueand therefore acts like$Truein a Boolean context).However, due to
Enable-NetFirewallRuleliving in a (different) module, it doesn't seeTestEnableNetFirewallRule's local$WhatIfPreferencevalue and therefore doesn't honor the original-WhatIfswitch.This problematic behavior is the subject of #4568.
juliank commentedon Apr 4, 2018
Thank you for the in-depth explanation Michael Klement (@mklement0). My knowledge of PowerShell is rather limited, and this difference in behavior between functions and compiled cmdlets was totally unknown to me (I guess I was just lucky when I posted #6342 a month ago, that it was an actual bug and not just a function/cmdlet issue).
From what I can read from #4568 which you mention, there doesn't seem to be any easy and straight-forward way of telling whether -WhatIf will behave as "expected" or not. So I guess the only thing I can do is to assume that it never will, and always test it? In any case it's an interesting discussion going on in the referenced issue thread.
mklement0 commentedon Apr 4, 2018
Julian Klock (@juliank): Thanks for the follow-up:
#6342 is indeed a manifestation of the same problem after all, as I've only just now realized.
If you do agree that #4568 is a problem, I encourage you to give it a thumbs-up - surprisingly few people have, so far.
Yes - unfortunately; to spell out the cumbersome workaround, using splatting:
Note that the above just covers
-WhatIf; to cover all common parameters, you'd have to apply the same logic to all of them.juliank commentedon Apr 4, 2018
Thank you for the suggested workaround Michael Klement (@mklement0). Splatting was new to me, so I would have gone for the even more cumbersome workaround surrounding my call to
Enable-NetFirewallRuleusingif (ShouldProcess(..., "...")). And if I read it correctly, it is easily adjustable to also account for-Confirm, which will cover my scenarios in this case.mklement0 commentedon Apr 4, 2018
Julian Klock (@juliank): Yes, it should work analogously for
-Confirm/$ConfirmPreference.