If you’ve been using PowerShell for any amount of time you’ve probably written a lot of code. Here are some guidelines I’ve come up with for what I consider “Professional” code. I should note that I’m assuming some basic things like correct verb-noun naming, commented code, reasonable variable names, etc. Also, the code should work! Once you’ve got that going, try to make sure you’ve got these as well.
- Output objects
This should go without saying, but it’s vitally important. Write objects to the output stream. Each object should be a self-contained a “record” of output. If you’re creating custom objects, consider including some of the parameter values that led to the object being output. If possible, It should contain enough information to let you know why it was output. For instance, if your parameters filter the output based on properties, including those properties will be very helpful in validating that the output is correct.
- Advanced functions (or script)
Changing a function into an advanced function can be as simple as adding [CmdletBinding()] before the Param() statement. It does take a bit more if you need to support -WhatIf and -Confirm, but even then it’s not much effort. In return you get:
- Common Parameter Support (Verbose, ErrorAction, etc.)
- Parameter Name and Position Checking
- Access to $PSCmdlet methods and properties
- Ability to use pipeline input (in a nice way)
If you need help getting started with writing advanced functions (or scripts), see about_Functions_CmdletBindingAttribute
- Comment-based help
This one takes a bit more work, but is a key to getting other people to use your function or script effectively. It’s simple to write up a code snippet for ISE (or your editor of choice) to include the help elements you like. Most people will start by skipping to the examples, so always include multiple examples! Examples which show different use-cases (parameter sets, if you use them, for instance) are especially helpful so that users understand the full range of how your code can be used. Refer to get-help about_Comment_Based_Help to get you started.
- Pipeline input
Pipeline input isn’t always necessary, but it really makes using a function easier. You’ve got to have an advanced function to do this, but you did that already, right? I’d much rather have this:
Get-Thing | Stop-Thing
Than this:
Get-Thing | foreach-object {Stop-Thing $_}
If you’ve used cmdlets that didn’t allow pipeline input you’ve undoubtedly written some code like this.
- Error Handling
This is pretty basic. You need to use try/catch/finally in your code to deal with exceptions that you can predict. You should use Write-Error and Throw to emit errors and exceptions that arise. If you use Write-Error, supply a -TargetObject if possible, it makes the error record much more useful. While we’re talking about errors, Write-Warning, Write-Verbose, and Write-Debug should be used to help provide useful output
- Parameter Attributes for validation
Here’s a good rule of thumb:
Code that you don’t write is code that you don’t have to debug!
If you use parameter attributes to validate argument values, you don’t have to write code to do it. Ensuring that arguments are valid will make users happier (because they don’t have unexpected results when they pass in bad values) and makes your code simpler because you don’t have to write a bunch of if/then statements to check values. Finally, and this benefit is not as obvious, error messages for parameter attribute-based validation will be localized, so users around the world can benefit even more from your code as they see validation messages in their own language..
- Publish it!
If you’ve put this much time into polishing your code, you should take the extra step of sharing it with the community. This might take a bit of extra effort to make sure it doesn’t contain anything proprietary. Sharing on your blog (you do have one, right?), GitHub, Technet, PoshCode, or the PowerShell Gallery
are all options, so there’s very little stopping you.
How does your code fare against this list? I know most of mine has some room for improvements.
What do you think of this list? Did I miss something important? Let me know in the comments!
–Mike
Great summery of howto make ones code more flexable and readable.
Thanks!
Can you write example for “Output Objects” or link where example is available
Create or pass on objects so that they can be reused. Either just output your “raw” result or make your own object (https://technet.microsoft.com/en-us/library/ff730946.aspx). Try to refrain from outputting formatted strings with write-host or equivalent from your functions/scripts. If you really want to make some “pretty” output, atleast make it an option with a switch parameter.
Great summary and one I’ll try to use everyday.