Forum Discussion

ThomasLehmann's avatar
ThomasLehmann
Copper Contributor
Feb 05, 2024

Import-Module for advanced functions doesn't work as expected

Using [CmdletBinding(SupportShouldProcess)] on functions using them inside the main script does work as expected: When passing -WhatIf or -Confirm:$true to the script then those parameters are passed to the advanced function too.

 

However when moving those function into a module (Example: Tools.psm1) the function is imported and can be called but those parameters are NOT passed to that function.

 

Any ideas are welcome.

 

Kind Regards,

Thomas

5 Replies

  • LainRobertson's avatar
    LainRobertson
    Silver Contributor

    ThomasLehmann 

     

    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

    • ThomasLehmann's avatar
      ThomasLehmann
      Copper Contributor

      LainRobertson 

      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)

       

       

      • LainRobertson's avatar
        LainRobertson
        Silver Contributor

        ThomasLehmann 

         

        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

Resources