Judge notes for event 3

This event's entries are impressive. Scoring appears to be higher than in the earlier events, so this one must have been easier to solve. So this time, instead of talking about good and bad scripts, I'm going to comment on some of the techniques I saw.

There was some "conversation" over whether Win32_Volume or Win32_LogicalDisk was the better approach to take. Fact is, either will return the requested data. So it really doesn't matter which one you use. The controversy seemed to include misreading or misunderstanding the requirement of reporting on "local hard drives", which implies that you need to use -Filter "DriveType=3" (or equivalent) with either to eliminate network or CD/DVD drives.

When passing a Path parameter into a function, it's a good practice to include [ValidateScript ({Test-Path -PathType Container})] in the definition to avoid having a file name passed in error. Doing the existence test for the path and creating it if necessary in the Begin section of the function would save some time over the various techniques used in the Process section.

One thing to remember when using a CIMSession is to close it when you've finished using it. A couple other points to pay attention to include accounting for the DCOM/WSMAN options when looking at remote computers and including #requires -version 3 in scripts that might be run by other people on computers that might not have PowerShell 3 installed.

Using a REGEX to validate a string parameter, such as a computer name, isn't a bad idea, but it's important to understand exactly what the match string means. As an example, some of the match strings included a pattern like this: "[a-zA-Z0-9.-]". This means all lower and upper case letters, any numeric digit, any character, or a minus sign. The any character (".") defeats the whole purpose of the match. It really should have been escaped to "\." to mean a period. This error would probably never appear due to the unlikelihood of a badly formatted computer name being fed into the function.

Lastly, a caution when including an optional credentials parameter. It's probably not a good idea to default it to an empty credential object ($Credential = [System.Management.Automation.PSCredential]::Empty). If you do a if ($Credential) {} call later in the script, it will always be $true and you may end up calling for the user to enter credentials far too many times. A better solution would be to check PSBoundParameters to see if a credential object was passed in.

Hope these ideas help. Good luck in Event 4.

About the Author

Art Beane

Howdy from Houston, TX. I’ve been consulting on how to use computers for almost 40 years, including everything from designing global networks to data centers to email, storage, virtualization, directories, automation and more. I’ve become a passionate user of PowerShell since it came out and use it whereever I can.

One Comment

  1. Just a quick note: '.' inside a character class (ie, inside square brackets) is just a '.'; it only means 'any character' when NOT in a character class.

    PS C:\Windows\system32> 'h' -match '[.]'
    False
    PS C:\Windows\system32> '.' -match '[.]'
    True