Write Verbose Output in PowerShell using Write-Verbose

It is good practice to use the various -Verbose, -Debug and other about_CommonParameters when writing functions because it helps one to write the clean code in a very integrated way with the PowerShell. This blog post focuses on the usage of Verbose command to provide detailed tracking information and status. One of the main benefits about using Write-Verbose command is that you can control, if you need extra detailed information. By default, the verbose message stream is not displayed, but you can display it by changing the value of the $VerbosePreference variable or using the Verbose common parameter in any command. Also, Write-Verbose writes to the verbose output stream and you can capture it separately.

Using the $VerbosePreference Variable

$VerbosePreference variable determines the Windows PowerShell responds to verbose messages generated by a script, cmdlet or provider, such as the messages
generated by the Write-Verbose cmdlet itself. This has 4 values: Stop, SilentlyContinue, Inquire and Continue. Out of these, SilentlyContinue value allows to supress the verbose output and is the Default value.

To understand the usage of this variable, consider below code snippet:


Write-Output 'Understand how $PreferenceVariable controls verbose output'
# prints current value of $verbosepreference
Write-Host "VerbosePreference is set to: $VerbosePreference"
# understanding how $VerbosePreference controls the verbose output
# case 1: set to bypass verbose stream
$VerbosePreference = "SilentlyContinue"
Write-Host "VerbosePreference is set to: $VerbosePreference"
Write-Verbose message "This line will not be shown"
Write-Verbose message "This line will be shown" Verbose
# case 2: set to output verbose stream
$VerbosePreference = "Continue"
Write-Host "VerbosePreference is set to: $VerbosePreference"
Write-Verbose message "This line will be shown"
Write-Verbose message "This line will not be shown" Verbose:$false
# remember to set the default value again
$VerbosePreference = "SilentlyContinue"

The output from above code snippet is as below:

control verbose output using verbosepreference variable

As its clear from above output, that if $VerbosePreference variable is set to SilentlyContinue, it will suppress the verbose output and if set to Continue, it will print the verbose output. However, when one uses the -Verbose option directly, it overrides the behavior defined by $VerbosePreference variable.

Using Verbose Output in Functions

To understand how we can control output from a Function, with using verbose parameter, consider below code:


Function Get-Sum {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number1,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number2
)
Begin {
Write-Verbose "Inside Begin Block: Get-Sum"
}
Process{
Write-Verbose "Inside process block: Get-Sum"
Write-Verbose "Adding both numbers: $Number1 and $Number2"
$Sum = $Number1 + $Number2
return $Sum
}
end {
Write-Verbose "In end block: Get-Sum"
}
}
# calls function without using verbose parameter
Write-host "Calling Get-Sum without using verbose parameter"
Get-Sum Number1 10 Number2 7
# calls function with using verbose parameter
Write-Host "Calling Get-Sum with using verbsose parameter"
Get-Sum Number1 10 Number2 7 Verbose

The output from this code is as below:

control output from function when using verbose parameter

There is not much to explain here. If we call the function with -Verbose parameter, it will honor the same and prints verbose output from all providers and cmdlet.

Cascading Verbose Output when using Multiple Functions

When you start using -Verbose parameter and you refactor your code, it is often necessary that you need to get Verbose output from all the functions who are being called from one another, so as to form the proper stack trace and output values. Thankfully, in PowerShell, you do not need to do anything special for doing this. PowerShell will first check if the first function was called or not using the -Verbose paramter and then automatically passes it on to the functions being called from inside of it.

Consider below code:


Function Get-Sum {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number1,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number2
)
Begin {
Write-Verbose "Inside Begin Block: Get-Sum"
}
Process{
Write-Verbose "Inside process block: Get-Sum"
Write-Verbose "Adding both numbers: $Number1 and $Number2"
$Sum = $Number1 + $Number2
return $Sum
}
end {
Write-Verbose "In end block: Get-Sum"
}
}
Function Get-Difference {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number1,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number2
)
Begin {
Write-Verbose "Inside Begin Block: Get-Difference"
}
Process{
Write-Verbose "Inside process block: Get-Difference"
Write-Verbose "Subtracting both numbers: $Number1 and $Number2"
$Diff = $Number1 $Number2
return $Diff
}
end {
Write-Verbose "In end block: Get-Difference"
}
}
Function Get-SumandDifference {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number1,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number2
)
Begin {
Write-Verbose "Inside Begin Block: Get-SumandDifference"
}
Process{
Write-Verbose "Inside process block: Get-SumandDifference"
$Sum = Get-Sum Number1 $Number1 Number2 $Number2
$Diff = Get-Difference Number1 $Number1 Number2 $Number2
Write-Host "Sum: $Sum"
Write-Host "Diff: $Diff"
}
end {
Write-Verbose "In end block: Get-SumandDifference"
}
}
# calls function without using verbose parameter
Write-host "Calling Get-SumandDifference without using verbose parameter"
Get-SumandDifference Number1 10 Number2 7
# calls function with using verbose parameter
Write-Host "Calling Get-SumandDifference with using verbsose parameter"
Get-SumandDifference Number1 10 Number2 7 Verbose

When we call the function Get-SumandDifference with -Verbose parameter, PowerShell notes down the same and passes it to functions Get-Sum and Get-Difference when calling the same. Below output confirms the same:

cascading verbose parameter from one function to another

Summary and Notes

PowerShell makes it easy to generate the Verbose output at times when needed and auto handles the underlying complexities. Using Write-Verbose and other common parameters helps one to write more maintainable code. It is also beneficial for other users, who are using your code, to use verbose output to figure out potential issues.

A copy of the source code used in this blog can be found at here on GitHub under blog/8409 and master branches.

The source code might not be shown, if you are opening this blog post using certain in-app browsers. In such a case, browse the post using proper browser on your device.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s