Scripting Games 2013: Event 2 Notes

I spent some time last week and this weekend to compile a list of notes of what I have seen with the Event 2 submissions that should show improvement. I touched up on some items with my previous article where I picked out some submissions that I liked and didn’t quite like but wanted to touch on a few more things. Some of this feels like a repeat of last week and even last years games, but that is Ok. This is all about learning and as long as everyone takes what all of the judges have been writing about, then there will be nothing but great improvements during the course of the games.

When is a one-liner not a one-liner?

The answer is when someone uses a semicolon “;” and assumes that counts as a one-liner. Sorry folks, but this doesn’t work. A one-liner is something that is a complete continuation of a string of commands. In PowerShell, a semicolon is a line break which means that the one-liner that was being put together has now became a multi-one-liner.

Here is what not to do:

$OS = Get-WMIObject -Class Win32_OperatingSystem ;$ComputerSystem = Get-WmiObject -Class Win32_ComputerSystem; New-Object PSObject -Property @{Computername=$ComputerSystem.Name;OS=$Os.Caption}

It seems like a one-liner, but with the semicolons, it is nothing more than a one-liner lie. In fact, the only time here that the semicolon is legal is with the New-Object cmdlet that takes a hash table as input.

A one liner is not required for the Scripting Games in the beginner event. It is a nice to have, but it is also a risk because if you try to force it as such, it could come back to bite you when it comes to voting. My advice, split the code up on lines because not only will it prevent possible issues in the code, it is going to look tons better!

Formatting your code

Moving from one-liners to proper code formatting so it can easily be read by not only the voting community, but also applies to production scripts that may have to be read 6 months from by someone else or even the future you. Think to yourself, “Will I know exactly what is going on here in 6 months?”. If you cannot answer this question or answer No, then stop, go back and take the time to re-format the code so it is more readable.

Here are some bullet points to think about when writing code:

  • Space out your code; separate by code blocks so it is not just one line after another of code
  • Use the proper line continuation characters: commas“,”, opening square bracket “{“ and pipe symbol “|”; please for the love of everything good, do not use a backtick “`” as a line continuation. This is also a lie and must be stopped!
  • Indent your code where needed. Examples would be when you use a natural line break (first bullet point) or during a ForEach/Where block and If/Else block. Doing so will make it easier to read and organize your code.

Splatting instead of back ticks for parameters

Splatting is not only great for working with various cmdlets and making input a lot easier when in a loop, but it is also a smart idea to make your code easier to read and avoiding the use of back ticks when working with multiple parameters.

Send-MailMessage -To user@domain.com `
                 -From user1@domain.com `
                 -Subject Test `
                 -SMTPServer server@domain.com `
                 -Body "This is a test"

This is not a good way of handling the parameters in a script. Sure, it is better than having them on one line and navigating that mess, but this still doesn’t fit a good practice. This is where splatting comes into play.

$email = @{
    To = 'user@domain.com'
    From = 'user1@domain.com'
    Subject = 'Test'
    SMTPServer = 'server.domain.com'
}
...
#Some code
...
#Add the output into the body of the email
$email.Body = $outputText
Send-MailMessage @email

I can define most of my parameters for Send-MailMessage up front and once I have the data available for my Body, I can add that into my $email hash table before calling Send-MailMessage and supplying the hash table into the cmdlet (using “@” to splat) and the command will run just like usual.

Enough with $ErrorActionPreference

I have seen a lot of people using $ErrorActionPreference up front in their submissions as a catch all for error handling. Sure, some people are using Stop or Continue (this is already the default). This should never be touched at all in a script unless there is an excellent reason to do so (so far there hasn’t been a reason to do so). Each cmdlet has a common parameter called –ErrorAction that accepts Continue, Inquire, Stop and SilentlyContinue that you can use. Unless you need to suppress error messages for some reason, then I would recommend using Stop and put this command in a Try/Catch statement to handle any errors that come up.

Format* fail

The last thing that I want to go over is the use of Format* cmdlets as a final step to output data to the user. Bad, bad idea! What you are doing is ruining the object for the user in a way that they cannot manipulate the output either through Sort or Where-Object and cannot even output this to a file ( it can be outputted to a .txt file, but it will be just like what is on screen, truncated and all).

Get-Service | Format-Table | Sort Name

image

Doesn’t work out so good, does it? If only the Format-Table wasn’t there, then I could have sorted this out.

Maybe this will work for a CSV file instead?

Get-Service | Format-Table | Export-Csv -NoTypeInformation Report.csv

image

No errors, so it had to have worked correctly, right? Wrong!

image

If you can read this, then you are a better person than me. Smile The same goes with Format-List as well. Format* cmdlets should never be used in a script and should be left for a user to make the decision themselves. It will save you the hassle of being asked why the output stinks and also save you from losing points in a submission.

That’s it for now. Hopefully you can use these tips not only for the Scripting Games but also for “real world” scripts in your environment as well!

This entry was posted in 2013 Scripting Games Judges Notes, powershell, Scripting Games 2013 and tagged , , . Bookmark the permalink.

3 Responses to Scripting Games 2013: Event 2 Notes

  1. Pingback: The 2013 Scripting Games, Beginner Event #2 | Mello's IT Musings

  2. What about splatting with Format table or ConvertTo-HTML? You know when using -Parameter in ConvertTo-HTML you can do @{Label=’Size’;Expression={“$($_/1GB) GB”}} or June describes it. http://powershell.org/wp/2013/04/29/name-that-property/

    • Boe Prox says:

      That really isn’t splatting. Splatting is specifying a hash table of parameters and values that can then be applied to a cmdlet. What you are showing is a calculated property that uses a name/value pair to output data. I wouldn’t ever recommend Format-Table in any case in a script as it will ruin the object with custom PowerShell formatting. Not quite sure what you mean by using -Parameter in ConvertTo-HTML…

Leave a comment