12
votes

I'm hoping to use the Write-Verbose commandlet in scripts and functions. It works as expected in script (.ps1) files, but not in module (.psm1) files--the commandlet is ignored in modules.

Running the following script:

PS> .\scaffold.ps1 -verbose

Produces:

VERBOSE: starting foo
path: c:\bar.txt
[missing entry here - 'verbose path: c:\bar.txt']
VERBOSE: ending foo

scaffold.ps1:

[cmdletbinding()]
param()

import-module Common -force

write-verbose "starting foo"

foo "c:\bar.txt"

write-verbose "ending foo"

Common.psm1:

function foo {

  [cmdletbinding()]
  Param(
    [string]$path
  )

  write-host "path: $path"
  write-verbose "verbose path: $path"

}

I haven't associated a manifest (.psd1) with the module (.psm1) at this point.

Is there a module-specific syntax that I need to use?

** edit **

What I need is a way to determine if the -verbose flag has been set on the .PS1 file so I can pass it to the .PSM1 file.

scaffold.ps1:

[cmdletbinding()]
param()

import-module Common -force

write-verbose "starting foo"

foo "c:\bar.txt" $verbose_flag # pass verbose setting to module based on what was set on the script itself

write-verbose "ending foo"
3

3 Answers

10
votes

To get Write-Verbose output from a cmdlet in a module, you need to use the -verbose common parameter. See http://technet.microsoft.com/en-us/magazine/ff677563.aspx

Using your code:

>import-module R:\Common.psm1
>foo "c:\users"
path: c:\users
>foo "c:\users" -verbose
path: c:\users
VERBOSE: verbose path: c:\users
8
votes

Found the answer here: How to properly use the -verbose and -debug parameters in custom cmdlet

scaffold.ps1:

[cmdletbinding()]
param()

import-module Common -force

write-verbose "starting foo"

foo "c:\bar.txt" -Verbose:($PSBoundParameters['Verbose'] -eq $true)

write-verbose "ending foo"
5
votes

The issue here is that variables in a caller's scope do not get picked up by code in a script module. When you call ".\scaffold.ps1 -verbose", $VerbosePreference is set to 'Continue' in scaffold.ps1's script scope. If you call a compiled Cmdlet from that script, it honors that $VerbosePreference value, but when you call Advanced Functions from a script module, they do not.

I've recently written a function that allows you to import the preference variables from the caller, using a combination of $PSCmdlet and $ExecutionContext.SessionState to get at the appropriate variable scopes. The call to this command, at the beginning of a script module's exported function, looks like this:

Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

The Get-CallerPreference function can be downloaded from http://gallery.technet.microsoft.com/scriptcenter/Inherit-Preference-82343b9d