Summary: Learn about using the free tool called ScriptCop to help write better Windows PowerShell scripts.
Microsoft Scripting Guy Ed Wilson here. This weekend we have a two-part series from James Brundage. Take it away, James!
Getting started with ScriptCop
One of the problems with a new and rapidly changing technology such as Windows PowerShell is that there’s very little common practice. Everyone writes code their own way, and solves similar problems in very different ways with very different side effects. Implementations are inconsistent.
There are many samples out there of good code, but very few checklists of what makes good code. Everyone starts out with the best intentions, but there has been nothing to help scripters do the “right” thing.
Developers tend to be slightly more irked by inconsistency than scripters, and so many languages have tools to help make sure people “do the right thing.” These tools look at information that you can find out about the source code or the DLL, but they do not run it. They just peek, analyze, and report back about what could be better. These tools are what are called “static analysis” tools, and they are a great thing to have in the toolkit.
ScriptCop is a static analysis tool for Windows PowerShell, to make sure your scripts are following the rules. ScriptCop has a number of built-in rules to help make your scripts better and to help avoid bugs. It’s also a framework for writing new rules, or writing “fixers” to help rewrite your code to do the right thing. You can run ScriptCop online, or download it from either http://scriptcop.start-automating.com or http://www.test-powershell.com/.
The main command you use in ScriptCop is Test-Command. You can either use Test-Command to tell you all of the issues in a single command, or you can have Test-Command tell you all of the issues in a module.
To get an idea of how it works, let’s go ahead and copy and paste a very simple function into ScriptCop online: http://scriptcop.start-automating.com/Test-Command.aspx. You can copy and paste one or more Windows PowerShell functions and test them in ScriptCop online. And you can test script files or modules you write by downloading ScriptCop and running it on your machine.
The function we’ll use will just be a simple “Hello, World”:
function HelloWorld
{
“Hello, World”
}
I paste the function into the ScriptBlock box in the online version of ScriptCop, as shown in the following figure.
After I test the function by clicking Test-Command, I get a simple to-do list to make the function better:
Rule |
Problem |
ItemWithProblem |
Test-CommandNamingConvention |
HelloWorld does not follow the verb-noun naming convention. PowerShell commands should be named like: StandardVerb-CustomNoun To see all of the standard verbs, run ‘Get-Verb’ |
HelloWorld |
Test-Help |
HelloWorld does not have a help topic |
HelloWorld |
Test-DocumentationQuality |
Code is sparsely documented (Only 0 % comments). |
HelloWorld |
Test-DocumentationQuality |
HelloWorld does not define any #regions or #endregion |
HelloWorld |
As you can see, each item clearly indicates which command (or module) had the problem, what the problem was, and which rule flagged the issue.
To see all of rules, run:
Get-ScriptCopRule
Each rule goes through a batch of information about the command. Some rules look at the help content the command generates; others look at the code that make up the script. Many rules simply look at basic parameter information to check that parameters are the right types. Because you can use ScriptCop online, you can always be sure you’re using the most up-to-date set of rules.
Let’s fix some of the stuff ScriptCop recommends. Here’s a function with some fixes:
function Show-HelloWorldOnComputerName
{
<#
.Synopsis
Sample Show-HelloWorld on remote machines
.Description
Actually, this does nothing; it’s there to demonstrate good scripting technique.
.Example
Show-HelloWorldOnComputerName
#>
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]
$ComputerName,
$Credential
)
#region Parameter Block
“hello world”
#endregion Parameter Block
}
When we run it thru the wringer again, it gives us:
Test-ForCommonParameterMistake |
Show-HelloWorldOnComputerName Credential parameter be a [Management.Automation.PSCredential] Parameter |
Show-HelloWorldOnComputerName |
Test-Help |
Not all parameters in Show-HelloWorldOnComputerName have help. Parameters without help: ComputerName Credential |
Show-HelloWorldOnComputerName |
Test-ProcessBlockImplemented |
Show-HelloWorldOnComputerName can take values from the pipeline, but has no process block |
Show-HelloWorldOnComputerName |
Test-ForCommonParameterMistake lets us know that credentials need to be of a certain type. Test-Help no longer complains that there is not a topic, but does complain about the lack of linked topics and about the lack of help on the ComputerName and CredentialParameter. Test-ProcessBlockImplemented points out a serious bug: there’s no process block (which means only the last item piped in will run).
With a few more slight changes, we’re clean:
function Show-HelloWorldOnComputerName
{
<#
.Synopsis
Sample Show-HelloWorld on remote machines
.Description
Actually, this does nothing, it’s there to demonstrate good scripting technique
.Example
Show-HelloWorldOnComputerName
.Link
Invoke-Command
#>
param(
# The remote computer name
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]
$ComputerName,
# the credential to connect
[Management.Automation.PSCredential]
$Credential
)
process {
#region Parameter Block
“hello world”
#endregion Parameter Block
}
}
ScriptCop gives you a simple, easy-to-use checklist of what’s left to fix with your scripts before they go out the door. Having static analysis tools such as this in your script kit can make it simple to perfectly and consistently polish every script on the way out the door.
Tune in tomorrow so that you can learn how to write your own ScriptCop rules, and how to run ScriptCop on a module.
Thanks, James!
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
0 comments