-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNew-YakeTimer.ps1
98 lines (82 loc) · 3.26 KB
/
New-YakeTimer.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
$yaketysaxfile = 'c:\yaketysax.wav' # This MUST be the full path.
<#
.Synopsis
Creates a timer with display
.DESCRIPTION
Creates a timer that writes the progress of the current action and the estimated remaining time.
Suppose you have $Items, an array of items to process.
First, you create a timer initialized to the number of items in the array:
$MyTimer = New-Timer -TotalItems $Items.count -Activity 'Processing items'
Then, while processing the items, you just call the next() function of the timer:
foreach ( $item in $Items ) {
# do things with $item
$MyTimer.next()
}
The progressbar is given a random Id, but the -Id parameter can be used to give all progressbars
in the script the same Id.
.EXAMPLE
$MyTimer = New-Timer -TotalItems 100
Creates a timer.
.EXAMPLE
$MyTimer.next()
Increments the timer.
.INPUTS
None
You cannot pipe input to this cmdlet.
.OUTPUTS
Object
New-Timer returns the timer object that is created.
#>
function New-Timer
{
[CmdletBinding()]
[OutputType([int])]
Param
(
# Total number of items to process
[Parameter(Mandatory=$true,Position=0)]
[int]$TotalItems,
# Activity name
[Parameter(Position=1)]
[string]$Activity = 'processing',
# Progressbar Id
[int]$Id = (Get-Random),
# For very long processes
[switch]$yaketysax
)
If ( $TotalItems -le 0 ) {
Throw 'The number of items must be positive'
}
$Timer = New-Object -TypeName psobject -Property @{
total = $TotalItems
current = 0
timer = [Diagnostics.Stopwatch]::StartNew()
activity = $Activity
id = $Id
media = $null
}
if ( $YaketySax ) {
$Timer.media = New-Object System.Media.SoundPlayer
$Timer.media.SoundLocation = $yaketysaxfile
$Timer.media.playlooping()
}
Add-Member -InputObject $Timer -MemberType ScriptProperty -Name percent -Value { ( 100 * $this.current / $this.total ) }
Add-Member -InputObject $Timer -MemberType ScriptProperty -Name timeleft -Value { ( $this.timer.ElapsedMilliseconds / (1000*$this.percent) ) * ( 100 - $this.percent ) }
Add-Member -InputObject $Timer -MemberType ScriptMethod -Name progress -Value { Write-Progress -Activity $this.activity -PercentComplete $this.percent -Id $this.id -SecondsRemaining $this.timeleft }
Add-Member -InputObject $Timer -MemberType ScriptMethod -Name next -Value { $this.current++ ; if ( $this.media -and $this.current -ge $this.total ) { $this.media.stop() } ; $this.progress() }
Add-Member -InputObject $Timer -MemberType ScriptMethod -Name done -Value { Write-Progress -Activity $this.activity -Id $this.id -Completed }
Return $Timer
}
#region demo
help New-Timer -ShowWindow
# array creation
$Items = 1..100
# timer initialisation
$timer = New-Timer -TotalItems $Items.count -Activity 'testing' -YaketySax
# timer use
$Items | % {
Write-Host test -ForegroundColor ( $_ % 16 ) # random treatment
Start-Sleep -Milliseconds 100 # let's make things slower for a better view
$timer.next() # increment timer.
}
#endregion