Scripting Games 2012: Know When To Use Format-Table

image

This was a common occurrence during the Scripting Games. Someone writing a great script or one liner that gave me everything that I needed. But then right at the end I see something like this:

| Format-Table

Ok, what is the big deal you ask? They are only outputting the data as a nicely formatted table which makes it easier to read on the console. Well, I won’t deny that it looks pretty on the console, but guess what you just did?

Well, the problem is that once you use Format-Table (or any of the Format* cmdlets for that matter) you immediately lose the original object that was being outputted by the previous command. This means that you cannot pipe the output into most commands as its new object type is not usable by other commands (except for some commands that redirect the output such as Out-File and such). Sorting no longer becomes an option as it doesn’t know how to deal with the new object. Don’t even bother trying to run an Export-CSV to output the data as a CSV file, because trust me, it will give you a pretty nicely unusable file that looks nothing like what you saw in the console.

Lets look as some simple examples here. First lets do a WMI query and look at an object and then pipe it into a Format-Table and see the object.

Get-WmiObject Win32_Service

image

Simple output from Get-WMIObject showing some information as a list. Not the easiest to read but it works great.

Get-WmiObject Win32_Service | Get-Member

image

As you can see, we have access to all of the properties and methods with this object. Now lets blow this useful object away with Format-Table.

Get-WmiObject Win32_Service | Format-Table

image

Sure, the output does look nice, but lets look under the hood at the new object.

Get-WmiObject Win32_Service | Format-Table | Get-Member

image

What you are seeing a whole lot of formatting of the object. All useful methods are gone and you cannot even see the properties anymore. Which leads into the next example: Sorting.

Get-WmiObject Win32_Service | Format-Table | Sort Name

What do you think will happen?

image

If your answer was fail, then congrats! As you can see this fails because of the new formatted object. If you try to pipe this into another cmdlet other than one that performs a redirection of output, you will become very familiar with this error message. What about using ForEach? Well, no error but at the same time, no output either.

Get-WmiObject Win32_Service | Format-Table | ForEach {$_.name}

image

Now I mentioned how writing to a CSV with Export-CSV would end in failure so let me show you just how pretty this output will be.

Get-WmiObject Win32_Service | Format-Table | Export-CSV -NoTypeInformation FTReport.csv
Invoke-Item FTReport.csv

image

Now that is a report that I would not want to send to my boss or anyone else for that matter. All you get now is a bunch of useless garbage that is taking up hard drive space.

Now I am not saying that you,  should never use Format-Table (or the other Format* cmdlets), I am just saying that use caution with them. In fact, unless you have a specific requirement to use these commands in  a script or function, DO NOT use them at all in your code! Leave it to the people using the script/function to decide if how they want to handle the object that you give them. Remember, the best thing you can do is give the original object if possible. Then they can do whatever they wish with it.

It is worth noting that some cmdlets output a table by default (Get-Process and Get-Service for instance) which can still be piped into another command or you can export to a CSV using Export-CSV. This is due to the  formatting files that are loaded when PowerShell starts up that define what is shown in a table format or list format but does not actually affect the original object itself. See this link some more information about these files. You can also run this command to get more information about formatting:

Help about_format

While not exactly on the same subject, one thing to keep in mind with one liners is this: Filter-Select-Sort. You want to filter as early as you can in the code to keep the returned objects as few as possible, then select only what you need and then sort/format the output.

So in closing, remember that while Format-Table does provide some nice output on the console, it can and will wreak havoc if you attempt to do much more with the newly formatted objects. Watch out when you use it!

Posted in powershell, Scripting Games 2012 | Tagged , , , | 3 Comments

Expert Commentator Post on Hey, Scripting Guy! For Advanced Event 2

imageMy Expert Commentator post on Hey, Scripting Guy! is live today. My focus today was on Advanced Event 2 with my own solution and explanation behind it. I had a fun time working on it and hope you enjoy it, too!

Expert Commentary: 2012 Scripting Games Advanced Event 2
Posted in News, powershell, Scripting Games 2012 | Tagged , , , | Leave a comment

Scripting Games 2012 Notes: Wait A Second, $True –eq “False”?!?

imageYes, what you are reading is correct,$True does in fact equal “False” in PowerShell. While this exact line was not used recently in the Scripting Games this year, people competing and submitting scripts did do something similar that gave a “false idea” that it was producing the correct data.

The event itself asked to find all running and stoppable services on a local or remote system. The solution was basically something like this:

Get-Service | Where {$_.CanStop}

Never mind that I am not using aliases or anything per the design guidelines as I am not worried about that here.

For the sake of a few examples, I am going to add a little more to this one-liner to get a more desirable output.

Get-Service | Where {$_.CanStop} | Select Name,CanStop

image

 

What I was instead seeing being submitted was something like this:

Get-Service | Where {$_.CanStop -eq "True"}

The reason for this is because it is already a boolean value and does not need to be evaluated to $True via a comparison. If you wanted to show all non-stoppable services, you would use the –Not (!) before $_.CanStop which would return all $False valued properties.

Again, lets add a little more to get a better output:

Get-Service | Where {$_.CanStop -eq "True"} | Select Name,CanStop

image

Hmmm…. Well, if you run this, it does in fact return the correct information, but let me say that it is a false sense of being correct. I will now show you why this is not the best way to perform a comparison against a property that has a boolean value.

Get-Service | Where {$_.CanStop -eq "False"} | Select Name,CanStop

image

Wait a second! We were looking for anything that was False, so why didn’t this work? Well, the short of it is that no matter what non-empty string value you use, it will always come back as $True when you compare it to $True.

$True -eq "True"
$True -eq "False"
$True -eq "Fish"

image

Pretty wild, isn’t it? Same goes for $False as well. If it is a non-empty string, it will always return $False.

$False -eq "False"
$False -eq "True"
$False -eq "Fish"

image

 

And to finish this little piece up, while non-empty strings are always $True, empty strings will always be $False:

$True -eq ""
$False -eq ""

image

Believe it or not, this is by design. In fact, there was a PowerShell Connect item submitted regarding this that was closed being “By Design”.

In designing the PowerShell language we based the semantics of the language on *successful* prior art wherever possible. PowerShell’s boolean behaviour is based on well-established existing behaviour in scripting languages including JavaScript, Perl, Python, PHP, AWK, the various UNIX shells, etc. All of these languages treat a non-empty string as true and an empty string as false. (Ruby and LUA are a bit different – all strings are true, even empty ones. This behaviour is inherited from LISP. In LISP nil is false, non-nil is true so all strings are true.)
Regarding loss of precision, using a value in a boolean context is considered an explicit conversion where loss of precision is permitted.
Having shipped Version 1 of PowerShell, changing the boolean behaviour would be a massive (and therefore unacceptable) breaking change.
All of that said, the semantics of V1 PowerShell are very oriented towards small programs. We are looking at adding a “super-strict” mode for writing larger programs where many of the implicit conversions may be suppressed and/or generate errors. Enforcing explicit boolean conversions might be something we could add. We will not add support for treating “true” as true and “false” as false as it’s not portable to a non-english locale.
-bruce

The Bruce answering this being the one and only Bruce Payette.

While this references V1, it continues to hold $True through V2 and the upcoming V3 Beta.

Keep this in mind when you are writing code so you do not have unintended consequences when your code is run or reported potentially inaccurate data.

Posted in powershell, Scripting Games 2012 | Tagged , , | 2 Comments

Scripting Games 2012: Quick Tips

Some things have really been standing out for me during the Scripting Games that I can’t contain anymore. So with that, here are a small list of things that you really really need to watch out for:

  • Know when to use Where-Object and when not to use Where-Object. Knowing this will help you avoid not only losing points on a script, but also can avoid impacting performance on your script. This also applies very well to Real-World scenarios.
  • Know how to deal with boolean values.
  • Know when to format your output and when not to format your output.
  • If the event says to do something, then do it. Failure to do so can and will cost you points.
  • Use of Get-Help and Get-Command will help you find that special cmdlet that will make your job a lot easier and then learn how to use it more efficiently.
  • Consider what you are planning on posting as your code and that you have ‘scrubbed’ it prior to submission.
  • If you are going to have “parameters” in your script/function, then read up on how to make them “parameters”. Think Param()…
  • Understand about line continuations. You can use |, { and ` to break the line and continue writing more code on the following line, but DO NOT combine these such as this:
Get-Process | `
Select Name,ID

This will work better:

Get-Process |	
Select, Name, ID

Ok, most of these are somewhat vague (and they are meant to be) and I will expand more on these after the games have completed. But consider these general guidelines to follow and think about when writing your code.

Posted in News, Scripting Games 2012 | Tagged , , | 1 Comment

Scripting Games After 1 Week

After the 1st week of the Scripting Games and as we now enter the 2nd week with event 6 today, I figured it was a good time to take a look at some of the things that I have seen during the games. There have been many, many script submitted this year, many more in fact than last year (which is awesome, by the way). Personally I have graded hundreds of scripts and continue to be amazed by all of the great scripts submitted this year. But as always, there are things that could always be improved on or perhaps some accidental mistakes made that could have turned a 3 or 4 star script into a 5 star script.

Now I am not giving out answers here, so look elsewhere Smile. Instead I am just going over some basic things that can help you out not only in the games, but elsewhere for that matter.

These are in no particular order of importance and should all be considered my opinion which does not reflect the other judges and their opinions.

Pay Attention To The Event Design Points

The design points are there for a reason. They are there to help you to help yourself get all 5 stars. If it calls for checking admin rights, then check for admin rights. If it says you can use aliases, then use them. If it says to write out a short novel about your hopes and dreams and then split it into into a hash table through osmosis, well… good luck with that, but still do it! By not following these design points, you are setting yourself up for heartbreak of not receiving all of the stars that you were hoping to achieve.

Don’t Forget About The Event Guidelines

On the other side of the coin, do not forget what you are supposed to be coding here. While design points will help you in your quest for a 5 star script, it will possibly crumble around you if you do not meet the actual goal of the script.

Less Can Sometimes Be More

Remember, writing a complex 500 line script that can get you the current date and time in 5 days is not always the best method to solve a problem. Unless you feel that you need to write more lines than necessary to solve a problem (and it really needs to be a good reason), you should try to make it with the least complexity as possible (have good comments if you can’t) and keep it as short as possible. This doesn’t mean skimp out on things, just use your best judgment to get the job done.

Slower Is Faster

Remember, you have 1 week from the time an event goes live to get it done and submitted. This is plenty of time to write the script and get it submitted prior to the deadline. It is better to turn it in later in the week and know it works the way it is supposed to then to submit it the same day it goes live and only get a couple of stars due to some mistakes. Your script will get rated regardless of when you submit it, so you have nothing to worry about.

Ask Questions

The moment the event goes live, you have the opportunity to ask questions on the Event article on Hey, Scripting Guy!. Not quite sure what it might be you are looking for, just ask! While the answers will not be given to you, Ed can provide some clarification to the event in the case that something just doesn’t make sense. Another reason to not be that first person to submit a script for the event after it goes live.

Research, Research, Research!

Look at previous Hey, Scripting Guy! articles. For that matter, look online for other articles that might relate to the event you are trying to solve. I can say that one of my own functions that I uploaded to the Script Repository made a big jump in activity since the games started up. You are not being help in a closed, locked room with only a laptop and an open connection to the poshcode site. So take advantage of what you have available to better align yourself with the correct method to solve each event.

Test Your Code!

This should go without saying. Make sure your code works before submitting. Try it out in various circumstances to make sure you cover all of the angles. Doing so will (hopefully) ensure that the code does not fail by the time we look at it, causing it to become a 1 star script. I have to admit that I have had the unfortunate task of giving a 5 star script only 1 star because it fails to run for me. Sad, but true. So take the extra time to test it out before submitting so you have one less thing to worry about.

 

Once the games close out, I will post some more things that I have seen, but am avoiding talking about until after the last event closes as I don’t want to give an unfair advantage to those folks who have yet to submit a script in various events. Just remember, this is  not only a competition, but also a great learning opportunity as well as a fun time to see how you do with other awesome PowerShellers!

Good luck in your second week of the Scripting Games!

Posted in powershell, Scripting Games 2012 | Tagged , | Leave a comment