Average Rating:

4.00 by 2 users.

31 Downloads, 84 Views

beginner10_2011.ps1

By: Dave Maldonado 21 Apr 2011 07:07 PM UTC in the category: Beginner Event 10

Description:

Measures time it takes to run a cmdlet or script block for a specified number of intervals and calculates the average. It sends results to console but can also email results of test to recipient if email parameters are supplied.
# Script: beginner10_2011.ps1
# Author: Dave Maldonado
# Date: 04/21/2011
# Comment: 2011 Scripting Games, Beginner, Event 10
  
<#
        .SCENARIO          
        Your boss is working on a script that needs to halt execution for five seconds and then check a specific value. 
		In the course of writing the script, your boss became concerned about the accuracy of using the Start-Sleep 
		Windows PowerShell cmdlet to halt execution for five seconds. The script is not going to be used to control a space 
		probe to mars, but it should be more accurate than a traditional egg timer. To be assured of the accuracy of the 
		Start-Sleep command, your boss asks that you measure the time the Start-Sleep command takes to pause for five seconds. 
		To check for variation, your boss wants you to take five measurements and provide the average time in milliseconds. 
		A satisfactory output could be as simple as seen here: "Average time of 5 runs of 5 seconds is 5007.84288 milliseconds"
		
		.DESIGN POINTS
		Extra points for the use of variables to allow for other scenarios than the one in this event
    	Extra points for clean code
   	 	Extra points for formatting output
		
		.SYNOPSIS
		Measures time it takes to run a cmdlet or script block for a specified number of intervals and calculates the average.
		It sends results to console but can also email results of test to recipient if email parameters are supplied.

		.DESCRIPTION
        Uses the command Measure-Command to measure the time it takes to run the cmdlet or script block. Also uses the 
		command Measure-Object to calculate the numerical average of all intervals run.

		.PARAMETER numberIntervals
        Specifies the number of intervals to run. For the purposes of this scenario, it will default to 5.

		.PARAMETER testScript
        Specifies the script block or cmdlet to run. For the purposes of this scenario, it will default to "Start-Sleep -seconds 5"

		.PARAMETER toEmail
        Specifies recipient's email address. There is no default. Will not send email if not provided.

		.PARAMETER fromEmail
        Specifies sender's email address. There is no default. Will not send email if not provided.

		.PARAMETER smtpServer
        Specifies SMTP Server to use. There is no default. Will not send email if not provided.
		
        .EXAMPLE
        C:\PS> beginner10_2011.ps1
		       
		Testing script: "Start-Sleep -Seconds 5"

		Test 1 of 5 Results: 5,002.1198 milliseconds
		Test 2 of 5 Results: 5,008.8930 milliseconds
		Test 3 of 5 Results: 5,008.8103 milliseconds
		Test 4 of 5 Results: 5,008.8237 milliseconds
		Test 5 of 5 Results: 5,008.3304 milliseconds

		Average time to complete 5 runs is 5007.3954 milliseconds.

		Description
		-----------
		With no email parameters entered, script will default to measuring the average time it takes to run 
		"Start-Sleep -seconds 5" over 5 intervals. Will send results to console only.
		
		.EXAMPLE
        C:\PS> beginner10_2011.ps1 -toEmail recipient@contoso.com -fromEmail sender@contoso.com -smtpServer smtp.contoso.com
		
		Description
		-----------
		With all email parameters supplied it will sends results to both console and email recipient. (Subject line will
		read "Boss - Here are the results of those tests you requested").		
#>

param (
	[int]$numberIntervals = 5,
	[scriptBlock]$testScript = {Start-Sleep -Seconds 5},
	[string]$toEmail, 
	[string]$fromEmail, 
	[string]$smtpServer
) # end Param

$style = '<style>
BODY{font-size:85%; font-family:arial; background-color:#D0D0D0}
TABLE{font-size:90%;border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse}
TH{font-size:100%; color:white; border-width: 1px;padding: 2px;border-style: solid;border-color:black;background-color:#000066}
TD{font-size:85%;border-width: 1px;padding: 2px;border-style: solid;border-color:black;background-color:white}
</style>' # end HTML Email Style

function Send-EMail {
    param(
	[string]$Subject="Boss - Here are the results of those tests you requested", 
	[string]$Body="<font face=arial><font size=2><B><U>Testing script: " + """$testScript""`
	</U></B></font><BR><BR>$TestResults <BR><BR><font face=arial><font size=2><B>The average `
	time of $numberIntervals runs is $RoundAverage milliseconds.</B></font>")
    $msg = new-object Net.Mail.MailMessage
    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
    $msg.From = $fromEmail
    $msg.To.Add($toEmail)
    $msg.Subject = $Subject
    $msg.IsBodyHtml = 1
    $msg.Body = $Body
    $msg.Priority = [System.Net.Mail.MailPriority]::High
    $smtp.Send($msg)
} # end function Send-EMail

Function Test-Script {
	# create array for collecting test results
	$Tests = @() 
	# create array averaging results
	$Times = @()
	# write summary to console
	Write-Host ("Testing script: " + """$testScript""")
	Write-Host
	# loop based of number of intervals defined
	For($i=1; $i -le $numberIntervals; $i++) {
	$Test = new-object PSObject
	# write output to console
	Write-Host -NoNewline ("Test" + "{0,2}" -f $i + " of" + "{0,2}" -f $numberIntervals + " " + "Results:")
	# measure the time (in milliseconds) it takes to run $testScript 
	$Time = (Measure-Command $testScript).TotalMilliseconds
	$Times += $Time
	# write output to console
	Write-Host -NoNewline (" {0,4:N4} milliseconds" -f $Time)
	Write-Host
	# build array with test values
	$Test | add-member -membertype NoteProperty -name "Test" -value ("{0,2}" -f $i)
	$Test | add-member -membertype NoteProperty -name "Results" -value (" {0,4:N4} milliseconds" -f $Time)
	$Tests += $Test
	}
	# calculate average of all interval times
	$Average = $Times | Measure-Object -average | Select-Object Average | ForEach-Object {$_.Average}
	# round average to 4 decimal places
	$RoundAverage = ([math]::Round(($Average),4))
	# write output to console
	Write-Host
	Write-Host "Average time to complete $numberIntervals runs is $RoundAverage milliseconds."
	# collect test results and convert to html for email
	$TestResults = $Tests | Select-Object * | ConvertTo-Html -head $style -body $style
	# if email params are specified, send email results to recipient
	if ($toEmail -and $fromEmail -and $smtpServer) {
		Send-Email
	}
} # end function Test-Script

# begin
Test-Script
# end
Top

Comments: