The 2013 Scripting Games started April 25th, and event 2 is now open for voting. As I did in event 1, I will pick out two entries from each event and provide some learning points to highlight both good and bad practices.
Before reading my comments, you might want to download the event instructions:
The first entry I will comment on is from Beginner 2:
Note: I am testing Gist as a way to share code snippets. I may need to edit the article after posting, please refresh your browser or go to the Gist URL manually if you do not see the code.
- I find using [System.Net.Dns]::GetHostEntry unnecessary in this case, as the name of the computers will be available from the WMI calls being used.
- Whether to use the foreach statement or the ForEach-Object cmdlet is not that relevant in this case, as saving the contents of a small text-file into memory does not consume much resources.
However, using Foreach-Object two times is unnecessary, there is nothing that prevents wrapping everything in one foreach-loop.
- The event instructions did not require you to provide alternate credentials. Since it is done anyway in this submission, I would rather save the credentials into a variable once and re-use that variable inside the foreach-loop. If not, the user will be prompted for credentials two times for each computer in the text-file.
- Re-writing the property names in the last line to make them more user-friendly is good, but there are some room for improvement in this line as well. Consider using Select-Object instead of Format-Table, this will make it up to the user what to do with the output. For example outputting them to a Csv-file using Export-Csv, or creating an HTML-report using ConvertTo-Html. Consider breaking the line into multiple lines to make it easier to read. Do not use aliases (ft in this case) when sharing a script, this makes it harder to read. Aliases are good though, when you work interactively in the shell and want to type as quickly as possible.
The second entry I have decided to comment on is from Advanced 2:
- The use of the #requires statement is good, since this function leverages new functionality in PowerShell 3.0 which would have caused errors in previous versions of PowerShell.
- Comment based help is leveraged in an excellent way, showing a very detailed description, help for each parameter, several examples, and what kind of object the function accepts as input and produces as output. .PARAMETER ShowProtocol is missing, although this parameter is documented in the description.
- The function accepts input from the pipeline by using [Parameter(ValueFromPipeline=$True)], which makes it possible to pipe the contents of a txt-file to the function as shown in one of the examples.
- A new Cim Session Option object is created in the begin block, defining DCOM as the protocol. This is a good example of showing how to use the begin block, which is typically used for operations that needs to be performed once for all of the objects that will be processed in the process block. One of the most common examples of using the begin block is connecting to a database server, but this function also shows another usage scenario.
- The new CIM cmdlets in PowerShell 3.0 is leveraged when WSMAN 3.0 is available, if not the legacy DCOM protocol is used. This way, the function will work against both newer systems like Windows Server 2012 as well as older systems like Windows 2000 Server. As stated in the description, “The Cim cmdlets have been used to gain maximum efficiency so only one connection will be made to each computer.”.
- Error handling is implemented, ensuring that even if the function is unable to connect to a computer, an object is returned stating that it was not possible to connect to the computer.
- Splatting is leveraged for passing parameters, see examples on line 71 and line 95.
- The function is outputting a custom object rather than text or formatting objects. This makes it up to the user using the function to decide what to do with the data. The new [ordered] syntax in PowerShell 3.0 is leveraged when creating the hash table which is passed to New-Object, in order to control the order of the properties of the custom object.
It has been fun to read through many of the great submissions made to event 2. Keep up the good work, and good luck with event 3 which starts May 9th.