We have finally hit the final event of the 2013 Scripting Games! The past 6 weeks have given us many amazing scripts and some that were in need of extra work. Regardless, for those of you who have finished all 6 scripts in your respective, I say Congratulations! You have hit the finish line sprinting hard to the end! Now you can sit back and know that you made it and have learned (hopefully) some great things along the way. Remember, not only have you learned some new techniques, but also the techniques that you have used have taught others how to write better scripts!
Now it is time to check out some of the good and bad things that I have noticed during Event 6.
Good
There were a lot of good things that I saw during this event, but some that stood out to me were the following:
[System.Management.Automation.Credential()]$LocalCred = [System.Management.Automation.PSCredential]::Empty
What is happening here is that a user could provide a PSCredential object into the $LocalCred parameter or just specify a username or even just specify the parameter like a switch. Quite a few options for just one parameter. The important thing here is the use of $LocalCred = [System.Management.Automation.PSCredential]::Empty which prevents a popup from occurring even if the parameter wasn’t used. Pretty important thing to keep in mind when adding a parameter for credentials.
Using –Confirm:$False to handle the ‘Are you sure?’ prompts was exactly what we were looking for in the requirement of avoiding these types of prompts and making the code as smooth as possible for someone to use.
Using Workflows was awesome as it allowed you to chain together different parts of the process to include adding information to the TrustedHosts, renaming a computer, performing a reboot during multiple parts of the process and ultimately adding the computer to the domain. Using workflows allows a more cleaner approach for areas like this when more than one operation needs to happen before another operation can be started. Good stuff!
Bad
The following is not a valid item for comment based help:
.REQUIREMENTS Requires PowerShell 3.0
Instead, the individual should have used the following valid way to show that PowerShell V3 is required:
#Requires -Version 3.0
Using ‘*’ in the TrustedHosts is a BAD idea! Very big security issue in that it means that the local system with this configuration will trust ANY remote system. Instead, it is better to only add the systems that are absolutely needed to avoid any unnecessary remote systems from accessing the local computer.
Lack of proper examples in the comment based help only hurts the overall self discovery of scripts and functions. Please make sure that you use at least 2-3 examples to cover the very basics of the function to something a little more advanced.
This one gave me a headache:
if ($WhatIf) { function WriteStatus($status) {Write-Host "WhatIf: $status"} } else { function WriteStatus($status) {Write-Verbose $status} }
This is really disappointing at this stage in the Scripting Games to see someone still trying to add their own –WhatIf/-Verbose/Help parameters in a function. PowerShell does all of this by itself, all you have to do it research a little to find out the proper way to accomplish this. Hint: take a look at [cmdletbinding(SupportsShouldProcess)] and also possibly using $pscmdlet.ShouldProcess() to make this really work for you.
Neutral
I added this for a couple of items that that showed a good practice or looked cool, but at the same time had some things that I didn’t quite like/agree with either. Hence, the neutral part.
I saw quite a few hard coded passwords in the scripts that left me wondering why. I get that the event called for passwords to be used and that it would be hard for others to reviewing to remember those passwords when running the code, so instead of it being in my bad list, it went the neutral. Because in the real world, you wouldn’t hard code a password in a script. I did like the person who attempted obfuscation of the password with RegEx:
(-join ("5040737377307264" -split "(?<=\G.{2})",19 | ForEach-Object {if ($_) {[char][int]"0x$_"}}) | ConvertTo-SecureString -AsPlainText -Force)
Still a security issue as the password can still be revealed, but at least it is a minute bit tougher for someone to figure out if they were just glancing at the code and didn’t try to run this snippet. Very cool!
Using New-Object –TypeName System.Management.Automation.PSCredential was something that I really didn’t think of doing, namely because I would whether prompt the user for credentials vs. using this and a hard coded password. Not exactly a bad thing in the submissions here, but I would be hesitant to use this in a real world script.
All in all, I have been very impressed with all of the submissions regardless of how good or not so good they were. I can honestly say that I learned some great tricks from the submissions. As I mentioned before, it is safe to say that everyone has learned something during these games, whether it has come from the community judging, the actual submissions themselves or from some of my fellow judges making their commentaries. Great job to everyone and I will see you all again for the next Scripting Games!
Pingback: Scripting Games 2013: Event 6 Notes | PowerShell.org