Marco Luzzara's answer is spot on (and deserves the bounty in my opinion) in regards to the module being run in its own session state, and that by design you can't access those variables.
An alternative solution to setting $VerbosePreference
and restoring it, is to have your module take a parameter specifically for this purpose. You touched on this a little bit by trying to add [CmdletBinding()]
to your module; the problem is you have no way to pass in named parameters, only unnamed arguments, via Import-Module -ArgumentList
, so you can't specifically pass in a $true
for -Verbose
.
Instead you can specify your own parameter and use it.
(psm1)
[CmdletBinding()]param([bool]$myverbose)
Write-Verbose "Message" -Verbose:$myverbose
followed with:
Import-Module test.psm1 -Force -ArgumentList $true
In the above example, it would apply only to a specific command, where you were setting -Verbose:$myverbose
every time.
But you could apply it to the module's $VerbosePreference
:
[CmdletBinding()]param([bool]$myverbose)
$VerbosePreference = if ($myverbose) { 'Continue' } else { 'SilentlyContinue' }
Write-Verbose "Message"
That way it applies throughout.
At this point I should mention the drawback of what I'm showing: you might notice I didn't include -Verbose
in the Import-Module
call, and that's because, it doesn't change the behavior inside the module. The verbose messages from inside will be shown purely based on the argument you passed in, regardless of the -Verbose
setting on Import-Module
.
An all-in-one solution then goes back to Marco's answer: manipulating $VerbosePreference
on the caller's side. I think it's the only way to get both behaviors aligned, but only if you don't use -Verbose
switch on Import-Module
to override.
On the other hand, within a scope, like within an advanced function that can take -Verbose
, setting the switch changes the local value of $VerbosePreference
. That can lead us to wrap Import-Module
in our own function:
function Import-ModuleVerbosely {
[CmdletBinding()]
param($Name, [Switch]$Force)
Import-Module $Name -Force:$Force
}
Great! Now we can call Import-ModuleVerbosely test.psm1 -Force -Verbose
. But... it didn't work. Import-Module
did recognize the verbose setting but it didn't make it down into the module this time.
Although I haven't been able to find a way to see it, I suspect it's because the variable is set to Private (even though Get-Variable
seems to say otherwise) and so that value doesn't make it this time. Whatever the reason.. we could go back to making our module accept a value. This time let's make it the same type for ease of use:
(psm1)
[CmdletBinding()]param([System.Management.Automation.ActionPreference]$myverbose)
if ($myverbose) { $VerbosePreference = $myverbose }
Write-Verbose "message"
Then let's change the function:
function Import-ModuleVerbosely {
[CmdletBinding()]
param($Name, [Switch]$Force)
Import-Module $Name -Force:$Force -ArgumentList $VerbosePreference
}
Hey now we're getting somewhere! But.. it's kind of clunky isn't it?
You could go farther with it, making a full on proxy function for Import-Module
, then making an alias to it called Import-Module
to replace the real one.
Ultimately you're trying to do something not really supported, so it depends how far you want to go.