While I’ve been judging entries in the 2010 Scripting Games, I’ve noticed a few things that I thought I would comment on here. In longer and complicated scripts, I’ve always suggested script developers provide some sort of feedback about what the script is doing. Typically this is done with Write-Host, but there are several ways you can approach this. Let me discuss a few variations.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
The first approach is to simply use Write-Host throughout the script to provide feedback or even debugging information. I always suggest using a different color to distinguish it from your script’s pipelined output. Here’s an example.
Param ([string]$computername=$env:computername) write-host "Starting script" -ForegroundColor Cyan write-host "Connecting to $computername" -ForegroundColor Cyan Get-WmiObject -ComputerName $computername -Class Win32_BIOS write-host "Ending Script" -ForegroundColor Cyan
For short scripts and situations where you always want the feedback, there’s nothing wrong with this approach. One variation I’ve seen, and have used myself in the past, is to make these statements contingent.
Param ([string]$computername=$env:computername, [switch]$verbose ) if ($verbose) {write-host "Starting script" -ForegroundColor Cyan} if ($verbose) {write-host "Connecting to $computername" `
-ForegroundColor Cyan} Get-WmiObject -ComputerName $computername -Class Win32_BIOS if ($verbose) {write-host "Ending Script" -ForegroundColor Cyan}
Now, the Write-Host lines will only execute if I’ve included –Verbose as a parameter. There’s nothing technically wrong with this approach. Although for my tastes it seems a bit heavy handed. A better variation, in my opinion, is to use Write-Verbose. This cmdlet will write a message to the verbose pipeline which by default is yellow text on a black background. Thus, the output doesn’t interfere with the script’s pipelined output and it is easily distinguished. You could simple keep the current version of my script sample and replace Write-Host with Write-Verbose, but there are two issues.
First, it is still clunky with all the If statements. Plus, by default the verbose pipeline is turned off. You need to set the $VerbosePreference to Continue to enable it. Here’s an even better way.
Param ([string]$computername=$env:computername, [switch]$verbose ) if ($verbose) { $verbosePreference="Continue"} write-verbose "Starting script" write-verbose "Connecting to $computername" Get-WmiObject -ComputerName $computername -Class Win32_BIOS write-verbose "Ending Script"
But wait…there’s more. PowerShell 2.0 let’s us write advanced functions and scripts that act like cmdlets which support the common parameters, including –verbose. All that is required is to tell PowerShell to treat the script or function as a cmdlet.
#requires -Version 2.0 [CmdletBinding()] Param ([string]$computername=$env:computername) write-verbose "Starting script" write-verbose "Connecting to $computername" Get-WmiObject -ComputerName $computername -Class Win32_BIOS write-verbose "Ending Script"
The [CmdletBinding()] directive must be before the Param statement. When I run the script and use –verbose, PowerShell will enable the verbose pipeline and I’ll see the output from all the Write-Verbose commands. No parameter, no verbose output. For that reason, I like including verbose output from the very beginning of script development. It provides useful feedback about what the code is doing and provides debug-type information about variables and the like. Plus the statements can serve double-duty as inline documentation.
Whether you use Write-Host or Write-Verbose ultimately is a matter of choice and scripting requirements and there’s no reason you can’t use both. You might always want information displayed to the person running the script, in which case Write-Host makes perfect sense. You can then use Write-Verbose for more detailed information. Including these commands from the beginning, makes troubleshooting scripts much, much easier.
Of course, if you really want to provide feedback, take some time to work with Write-Progress. But that’s a topic for another day.
Thanx Jeff ! very useful.
Thanks. Any hints about how to use the Powershell common parameter -Verbose in a powershell script? I haven’t been able to get it to work, and I can’t find any documentation on how to use it.
In a script, you can use -verbose with any cmdlet. Whether it will do anything is a different matter. The cmdlet must be written to use the parameter if passed, much the same way as in my function example. Unfortunately you just have to try it and see if it works, but don’t be surprised if you get no verbose output.