I was looking for a way to determine whether I was in Verbose mode in Powershell. My web searches came up with various solutions that all suffer from problems. Most of them use $PSBoundParameters
. The most obvious problem with this is that it only works when -Verbose
was called directly on the script or function whose context you’re currently in. Since the Verbose state is inherited by child scopes, this is less than ideal.
What is Verbose anyway?
For this, it’s best to see the documentation on Preference Variables:
$VerbosePreference ------------------ Determines how Windows PowerShell responds to verbose messages generated by a script, cmdlet or provider, such as the messages generated by the Write-Verbose cmdlet. Typically, verbose messages describe the actions performed to execute a command. By default, verbose messages are not displayed, but you can change this behavior by changing the value of $VerbosePreference. You can also use the Verbose common parameter of a cmdlet to display or hide the verbose messages for a specific command. For more information, type: "get-help about_commonparameters". Valid values: Stop: Displays the verbose message and an error message and then stops executing. Inquire: Displays the verbose message and then displays a prompt that asks you whether you want to continue. Continue: Displays the verbose message and then continues with execution. SilentlyContinue: Does not display the verbose message. Continues executing. (Default)
From this we can see that it’s not actually a binary state, but a collection of 4 possible settings with different behavior.
When a script or function is called with -Verbose
, it sets the $VerbosePreference
variable in that scope to Continue
.
If the function is not called with -Verbose
, then it can still inherit $VerbosePreference
from its parent scope, which could have had it set explicitly or implicitly from anywhere up the stack. $VerbosePreference
might also have been set manually to Stop
or Inquire
.
Testing for Verbosity
So in order to test, you can just check the current value of $VerbosePreference
to see which of the 4 states it’s in. Or a more simple boolean check might look like this:
Before realizing this, I came up with another one-liner:
This one works by writing something on the verbose stream, redirecting it to stdout, and then casting it to [bool]
. This check is nice because it implicitly uses the same criteria as Write-Verbose
does. It still feels a bit wrong to me though.
Wrapping Up
Either of these can be wrapped into a small function:
From what I can tell, both of these tests work in all of the following situations:
-
Explicitly calling the current function with
-Verbose
-
The above (but calling a script)
-
Inheriting
$VerbosePreference
from a parent scope -
Explicitly setting
$VerbosePreference
-
Explicitly undoing an existing state with
-Verbose:$false
This should all apply to -Debug
and $DebugPreference
as well, but I haven’t tested. Let me know if you do!