Skip to content

Suggestion :: Write-Verbose Behaviour when packaged in a module  #3106

Closed

Description

@JohnLBevan

When Write-Verbose is included in a function or cmdlet in a module file, it doesn't behave in the same way as it would had that function been written in the main script file. i.e.

# MyScript.ps1
[CmdletBinding()]
param()
 
function Invoke-Demo {
    [CmdletBinding()]
    param ([Parameter()][string]$Message)
    process {Write-Verbose $Message}
}
 
Invoke-Demo 'This DOES show when I run ".\MyScript.ps1 -Verbose"'
Write-Verbose 'This DOES show when I run ".\MyScript.ps1 -Verbose"'

Behaves differently to:

# MyModule.psm1
function Invoke-Demo {
    [CmdletBinding()]
    param ([Parameter()][string]$Message)
    process {Write-Verbose $Message}
}
# MyScript.ps1
[CmdletBinding()]
param()
Import-Module -Path '.\MyModule.psm1' -Force
Invoke-Demo 'This does NOT show when I run ".\MyScript.ps1 -Verbose"'
Write-Verbose 'This DOES show when I run ".\MyScript.ps1 -Verbose"'

This seems counter intuitive, and overly complex to get write-verbose to function based on whether the script is being run with the verbose switch enabled.


Suggested Solution
Since there may be a design reason for this behaviour, it's likely best that any new behaviour be controlled explicitly. As such I'd suggest enabling Write-Verbose to function as desired by including a switch when importing the module; i.e.

Import-Module -Path '.\MyModule.psm1' -Force -InheritVerbose

More information here: https://developer42.wordpress.com/2017/02/04/powershell-suggestion-simplify-write-verbose-in-modules/

Activity

  1. joeypiccola commented on May 3, 2017

    @joeypiccola

    I hit this a few years back, was hoping it was figured out.

  2. mklement0 commented on Apr 7, 2018

    @mklement0
    Contributor

    It took a while to emerge, but this is actually the more fundamental issue discussed in #4568:

    Inheritance of common parameters - not just -Verbose, but notably also -WhatIf - via advanced functions relies on implicitly set local preference variables:

    A common parameter, such as -Verbose, passed to an advanced function is function-internally automatically translated into an equivalent local preference variable_, such as $VerbosePreference.

    This inheritance mechanism ONLY works:

    • when invoking binary cmdlets, which do see and respect the local preference variable.
    • when calling scripts / other functions in the same module scope as the caller.

    By contrast, a function from a different module cannot see the caller's local preference variable, due to how module scopes function fundamentally.

    In short: the common-parameter inheritance mechanism is fundamentally broken for advanced functions across module scopes.

  3. ThomasNieto commented on Aug 18, 2023

    @ThomasNieto
    Contributor

    Steven Bucher (@StevenBucher98) should this be closed as a duplicate/related to #4568?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugResolution-DuplicateThe issue is a duplicate.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions