Judge Notes for Event 1

 A lot of you have been working too hard at solving the problem (both beginner and advanced). Some of this is clearly related to trying to offer a very complete solution but some look like attempts to write extra clever or elegant code. In the “real world”, there’s probably not enough time or interest in putting lots of effort into these extras. The minimum it takes to achieve the goal is most often good enough. Here are a couple of examples to illustrate this (with the intent of providing a learning opportunity).

Working with the destination folder address.

A common error here was missing the subdirectory. Most folks got this correct by using some version of $_.FullName.Replace(‘C:\Application\Log’,’\\NASServer\Archives’) or Join-Path ‘\\NASServer\Archives’ $_.Directory.Name, but there were a number who just used the root destination folder name without looking for the subfolder. And some others had solutions that (although I thought were innovative), took too much effort. Among them are:

Join-Path ‘\\NASServer\Archives’ ($_.Directory.Split(‘\’)[-1])

$_.FullName –Replace [regex]::Escape(‘C:\Application\Log’,’\\NASServer\Archives’)

Once computing the destination, most solutions checked to see if the folder existed and created it if it was missing. But some just tried to create it anyway (too much effort) and others who did not (too little effort).

I’m not going to comment on the use of Copy-Object vs. Move-Object other than to say that (related to the destination folder) it looks like some people thought the cmdlets would create the path structure but never tested to see that they don’t. Don't forget to test your solution to verify that it works: working code is far more important that "pretty" or "elegant" code.

Using Try-Catch-Finally.

Try-Catch-Finally is an awesomely potent construct but you really need to understand how it works. Here's why I think it is serious overkill for this problem. Compare these:

If (-not (Test-Path $DestinationFolder)) {New-Item –ItemType Directory –Path $DestinationFolder}
Try {Test-Path $DestinationFolder –ErrorAction Stop} Catch {New-Item –ItemType Directory –Path $DestinationFolder}

Look the same, right? But they have very different results, not to mention different typing efforts. If the destination folder does not exist, then with IF, the folder gets created, but with Try-Catch it will not. This is because Test-Path will return $false, but NO error, so the catch clause will never execute.

Most folks understand that a terminating error has to occur in the Try script block in order for the Catch block to execute. But, instead of using the –ErrorAction Stop parameter in the cmdlet, some of the solutions set $ErrorActionPreference to Stop and then reset it to Continue in a Finally block. There are two problems with this. First, it forces every command in the Try block to generate terminating errors, when there’s normally only one that you care about. Second, $ErrorActionPreference might not have been originally set to Continue. Shouldn’t the previous value be saved and then restored in Finally?

So, going forward, think about how hard you’re working to get to an answer. Don’t use a more complex method than you need to in order to solve a problem. Make good use of Get-Help to verify the parameters and outputs of the cmdlets that you use. And test your objects with Format-List and Get-Member to make sure that the properties really are what you think they are.

 

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. But this isn't the real world. It's a game.

    It's one thing to tell someone that they're overcomplicating the problem, but it's completely another thing to tell them that they're putting too much effort and to just do the minimum. Again, this is not the real world.

    If it were the real world, the responsible thing to do would be to use robocopy.

    If someone wanted to learn regex, the responsible thing to do is to try it out on games like these instead of trying it first on real world scripts. If someone wanted to learn how to use try/catch/finally, the responsible thing to do is to try it out on games like these instead of trying it first on the real world scripts.

    Give them a bad score if you want. They should expect it. But it's their six weeks. If they want to write everything in regex and use try/catch/finally everywhere they can because they would rather mess up now, on a bunch games, instead of making those mistakes in the real world (because they know that they will make mistakes eventually), then so be it.

    You can and should give them a bad score. But you shouldn't tell them to stop putting that kind of effort, because maybe, by doing some seemingly impractical things in games, they end up being very practical in the real world.

    I apologize for unloading like this on your post.