Forum Discussion
Import-Module for advanced functions doesn't work as expected
Hi, Thomas.
WhatIf is a bit of a dog's breakfast and always has been, but it does work across both "live" functions as well as an exported module member - in its own odd fashion.
Given you're already familiar with using WhatIf in a "live" setting, I'll provide an example for the module context.
Example module
function Invoke-Wazzup
{
[cmdletbinding(SupportsShouldProcess=$true)]
param(
[parameter(ValueFromPipeline=$true)] $Stuff
)
begin
{
Write-Verbose -Verbose -Message "Prepare yourself... ($WhatIfPreference)";
}
process
{
if ($true -eq $WhatIfPreference)
{
Write-Information -InformationAction:Continue -MessageData "We thought about writing something witty, but -WhatIf says ""NO!""";
}
else
{
Write-Verbose -Verbose -Message "Wazzup?! Oh, the input was:";
$_;
}
}
end
{
Write-Verbose -Verbose -Message "Yep, we're done.";
}
}
Export-ModuleMember -Function @("Invoke-Wazzup");
Example use and output
Under "normal" circumstances, you might expect to see a variable named "$WhatIf" added where you would proceed to use it the same as any other switch via the .IsPresent() method, but WhatIf isn't like that.
Instead, providing the WhatIf parameter for the command changes the value of the $WhatIfPreference variable within the localised scope. So, in my function above, when I provide -WhatIf when calling the function, then $WhatIfPreference = $true only inside the function.
Cheers,
Lain
- ThomasLehmannFeb 05, 2024Copper Contributor
My Module function (test) looks like following:
function Test-WriteMessage { [CmdletBinding(SupportsShouldProcess=$true)] param ([String] $Message) Write-Message "-WhatIf:$WhatIfPreference -Confirm:$ConfirmPreference" if ($PSCmdlet.ShouldProcess($Message, 'Writing a message')) { Write-Message $Message } else { Write-Message "$Message (simulated)" } }And my main.ps1 looks like following:
[CmdletBinding(SupportsShouldProcess)] param() Import-Module $PSScriptRoot\Tools -Force Write-Debug "is just a test" Write-Message "hello world!" Test-WriteMessage "hello world!"When calling .\Main.ps1 -WhatIf then I get
hello world!
-WhatIf:False -Confirm:High
hello world!However when moving the Test-WriteMessage into "Main.ps1":
hello world!
-WhatIf:True -Confirm:High
What if: Performing the operation "Writing a message" on target "hello world!".
hello world! (simulated)- LainRobertsonFeb 05, 2024Silver Contributor
I missed a third test, where you're passing -WhatIf into the script, however, I had no issues with this, either.
Adjusted script (.\forum.ps1)
[cmdletbinding(SupportsShouldProcess=$true)] param(); Import-Module -Name .\Forum.psm1; Test-WriteMessage -Message "Foo" -WhatIf:$WhatIfPreference; Remove-Module -Name "Forum" -WhatIf:$false;Output
Cheers,
Lain
- ThomasLehmannFeb 05, 2024Copper Contributorok ... always passing -WhatIf:$WhatIfPreference (and same for confirm) does work (of course). However it is weird since it mean that SupportsShouldProcess is less intuitive to use since there is not much left to simply define those parameters myself. The automatically passing through all functions that do support the ShouldProcess was the real benefit which has gone moving those functions into a module.
Anyway, thanks for your help
- LainRobertsonFeb 05, 2024Silver Contributor
Hi, Thomas.
I changed your example a little as I have no such commandlet as "Write-Message", but that has no bearing on the test itself, which was successful for me both from the command line and indirectly via a script.
Module (forum.psm1)
function Test-WriteMessage { [CmdletBinding(SupportsShouldProcess=$true)] param ([String] $Message) Write-Information -InformationAction:Continue -MessageData "-WhatIf:$WhatIfPreference -Confirm:$ConfirmPreference"; if ($PSCmdlet.ShouldProcess($Message, 'Writing a message')) { Write-Information -InformationAction:Continue -MessageData $Message; } else { Write-Information -InformationAction:Continue -MessageData "$Message (simulated)"; } } Export-ModuleMember -Function @( "Test-WriteMessage" );Command line test
PowerShell script test (.\forums.ps1 - not to be confused with the above .psm1)
Import-Module -Name .\forum.psm1; Test-WriteMessage -Message "Foo"; Test-WriteMessage -Message "Foo" -WhatIf; Remove-Module -Name "Forum";So, whether the function is called live or via a script, your example is working for me.
It's worth noting that in your example main.ps1, you're never calling your function with the -WhatIf parameter. I'm assuming while testing you are remembering to do that.
Cheers,
Lain