Saturday, July 4, 2009

Super Duper Over-Engineered Egg Timer


This was my submission for Event 10 Beginner of the 2009 Scripting Games this year. I usedPrimalForms to design the form and generate the boilerplate code. It's a really great tool.

I added the timer functionality myself. The Windows.Forms.Timer object is very simple. You tell it how frequent to set the ticks, set it to enabled or disabled, and call Start() to kick it off. The Timer itself doesn't keep track of how long it has been going, you do that by adding an event handler for the Tick event. You do that as seen on line 5 below, by calling add_tick() on the Timer object and passing it a script block that will be called every time the event fires. As far as I can tell this should work for any Windows.Forms object, calling add_event(), where "event" is the name of the event you are adding a handler for. The interval is in miliseconds, so in this case
the scriptblock $timer1_OnTick will be called once every second.

I went ahead and gathered the relevant lines in one place below so it's easier to see what I did. They're kind of spread around in the actual script.

  1. $timer1 = New-Object System.Windows.Forms.Timer
  2. $timer1.Enabled = $true
  3. $timer1.Start()
  4. $timer1.Interval = 1000
  5. $timer1.add_tick($timer1_OnTick)




Tuesday, June 30, 2009

Recursively Getting All Folder Sizes

This started out as my entry for Event 8 in the Microsoft Scripting Games 2009 (see more entries here), but it's useful, so I think I'll keep it. This function uses recursion to work its way down the directory tree and get all folders and their sizes, and outputs them as psobjects for easy sorting, etc. It's not the fastest thing in the world, but it does the trick. Make sure to check out the examples in the help documentation.





Tuesday, June 9, 2009

The 2009 Scripting Games!

So the 2009 Scripting Games have begun! There are 10 events this year, and the theme is decathalon. This is my first year participating. The next few posts will be my solutions. Check out the Script Center for updates and event details.

Sunday, May 31, 2009

Using Strict Mode with Set-PSDebug

If you've used Perl in the past, then you're probably familiar with "use strict" (if you've been using Perl without "use strict", then head over here Note: the scoping issues don't apply to PowerShell).

By default, PowerShell is very accommodating. If you tell it to echo the value of $chouderhead, it will happily echo... NOTHING! There is no variable called $chouderhead, you misspelled $chowderhead. PowerShell doesn't like to make waves, though, so it happily creates a new variable named $chouderhead and starts using it. This can lead to very hard-to-debug issues.

You can fix this By adding this line to your profile (or just typing it in at the prompt):

PS> Set-PSDebug -strict

Now if you try to use a variable that hasn't yet had a value assigned to it, you'll get an error like this:

PS> $chouderhead
The variable '$chouderhead' cannot be retrieved because it has not been set.
At line:1 char:13
+ $chouderhead <<<<
+ CategoryInfo : InvalidOperation: (chouderhead:Token) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined

The error is annoying, but if you've ever wasted a half an hour wondering why your script isn't outputting what you thought it would, only to realize that on line 304 you accidentally used an 'm' instead of an 'n' in your variable name and how could I miss that, it's so stupid, and now I missed dinner, and my back hurts from crouching over my keyboard staring at the screen for too long and curse the day I was born! Why, oh, why didn't I just add 'PSDebug -strict' to my profile? Why?

But I digress...

Tuesday, May 19, 2009

Get-ChildItemRecurse Update

Someone named CrazyDave made an important update to the script I made yesterday. I was checking for the specific type System.IO.DirectoryInfo. The problem with this is, it unnecessarily limits my script to being used on files and folders. Get-ChildItem makes no such distinction. It can be used on any PSDrive.

So here is the corrected version: http://poshcode.org/1115 (highlighted line is the old one)



Monday, May 18, 2009

A Get-ChildItem Wrapper That Lets You Say How Deep to Recurse

I noticed that a couple of people hit my blog that seemed to be looking for a script like this, and it turned out to be an interesting exercise.

Notice that I took the fileglob and moved it down the script rather than just using it in my call to Get-ChildItem. I had to do that because otherwise I would only have been recursing through directories that matched the pattern, and I wanted to recurse down into all directories, but only send those entries that match the pattern down the pipeline.

The function is here, for those that don't see it inline in the post: http://poshcode.org/1113



Sunday, May 3, 2009

Use PowerShell to Recursively Get Group Members

I've noticed looking at my StatCounter logs that a few people found my post on recursion while looking for a way to recursively get group members in PowerShell, so I whipped up this script.

Note that it depends on the AD Cmdlets from Quest, and that it works in much the same way as the example. Whenever it finds that one of the group members is a group, it calls itself on that group and adds the result to the list of users.

Also note the technique of using a hashtable to keep a list of unique users. It's common to store a list in an array and use use -contains and -notcontains to find out if an item already exists, but this is tremendously inefficient compared to using a hashtable as an index, especially as the list of users gets longer, because it has to keep cycling through the list over and over. It's a trick I picked up in Perl that works equally well here.