Expert Solution for 2011 Scripting Games Beginner Event 10: Use Easy PowerShell Code to Time Script Operations

Summary: Microsoft PowerShell MVP Marco Shaw solves beginner event 10 in the 2011 Scripting Games and shows how to time script operations

Microsoft Scripting Guy, Ed Wilson, here. Marco Shaw is the author of the expert commentary for Beginner Event 10.

Photo of Marco Shaw

Marco is a consultant with CGI in Moncton. He has been working in the IT industry for over 12 years, also working for Bell Aliant and Atlantic Lottery. He was awarded the Microsoft MVP award for his contributions to the Windows PowerShell community in 2007, 2008, 2009, and 2010. His recent authoring activities have included writing Windows PowerShell content for a Windows Server 2008 book published by Microsoft Press and writing a Windows PowerShell-related article on System Center Operations Manager 2007 for TechNet Magazine. He also provided Windows PowerShell content for a SQL Server 2008 book by SAMs publishing company and for a just released revised edition of System Center Operations Manager 2007 Unleashed by SAMs. He also coauthored the 2nd edition of PowerShell Unleashed published by SAMs, which was released early in 2009. He has spoken at Microsoft TechDays in Halifax, Canada the last two years where he has delivered sessions on System Center Operations Manager 2007 R2, Windows Server 2008 R2, and Windows PowerShell.

Worked solution

My task was to write a solution for Beginner Event 10. Based on my IT-related work experience, I always make sure that I have a decent grasp of the requirements before I start any kind of solution to a problem or question. I love to ask questions, sometimes to the chagrin of others (but I did well in a short meeting at work today).

I thoroughly read the problem and the desired output and extra points. Then I read it again, and because this only takes 60 seconds of my, sometimes-uneventful life, I read it again!

All right, after those three minutes of reading, I need to fire up my Windows PowerShell ISE.

Thinking about the desired output, I think New-TimeSpan is the only cmdlet that can output values in milliseconds. I have to check this out:

new-timespan get-date (get-date).addseconds(5)

That outputs an error—how about wrapping the values to compare sothey are evaluated properly?

new-timespan (get-date) ((get-date).addseconds(5))

I always forget that with Compare-Object also. That works!

Remembering the bonus points, this approach will allow me to easily add a variable for the 5. I also want to set up a simple variable to set the number of runs, which I should be able to easily use with the start_number…end_number syntax.

I know the Measure-Object cmdlet also has an average parameter switch. Enough thinking, my head is starting to hurt. Let’s try this out.

1..5|foreach{new-timespan (get-date) ((get-date).addseconds(5))|select -exp totalmilliseconds}|measure-object -average

I’m sticking with a one-liner for the time being.

OK, that doesn’t seem to provide the same level of exactness as the sample code, but the problem doesn’t define what it should be either (and there are no bonus points for that either). I’m not going to overcomplicate a solution when it isn’t a requirement or other incentive.

One final change to display only the average:

$avg=1..5|foreach{new-timespan (get-date) ((get-date).addseconds(5))|select -exp totalmilliseconds}|measure-object -average|select -expand average

It’s getting longer.

Now, when it comes to output, I prefer to write a simple string with variables to the console, but let’s make this one a bit more PowerShell-y…

Now I never remember how to use the -f format operator, so off to Bing.com I go…

OK, here’s what I have coded in the ISE:

$tries=5

$seconds=5

$avg=1..$tries|foreach-object{

  new-timespan (get-date) ((get-date).addseconds($seconds))|select-object -expand totalmilliseconds

}|measure-object -average|select-object -expand average

“Average time of {0} runs of {1} seconds is {2} milliseconds” -f $tries,$seconds,$avg

Trying to stick with a one-liner for $avg makes it a bit harder to read. I always indent my code with two spaces. That’s just a personal thing though…some like using a tab.

It works!

Thank you for your solution, Marco.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy