-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSet-TimedPrompt.ps1
More file actions
169 lines (130 loc) · 4.73 KB
/
Set-TimedPrompt.ps1
File metadata and controls
169 lines (130 loc) · 4.73 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
Function Set-TimedPrompt {
<#
.SYNOPSIS
A choice prompt with a timeout
.DESCRIPTION
A 'simple' way to create a prompt that will timeout and automatically select a default.
You can provide a prompt, the possible options (or answers), and a timeout value. This
function will try to select a single keystroke to choose the various options, or use a
number if that letter is not available. You can also provide your own key by putting
an ampersand ('&') before your letter.
The counter will change from green to yellow to red depending how much time is left.
The function returns an object that contains:
Response : The original text of the option (ampersand included if present)
NoAmp : The original text with any ampersand removed
ActionKey: The key to select
The ToString() method of the object will return the Response text
.PARAMETER Prompt
The text to prompt or question for the user
.PARAMETER SecondsToWait
How long the script will wait before selecting the default
.PARAMETER Options
A string array of options to choose from. The first option will be the default. Use an
ampersand to hard set a keystroke to select, otherwise, the first character will be used
(or a number if the character is already taken). Eg. "Heck &Yes" = Y; "Heck No" = H
.EXAMPLE
Set-TimedPrompt -Prompt "Which Way?" -Options "Up", "Down" -SecondsToWait 60
Which Way?
U : Up
D : Down
Default is 'Up' in 58
Response
--------
Up
.EXAMPLE
Set-TimedPrompt -Prompt "Which Way?" -Options "U&p", "Down", "Don't Know" -SecondsToWait 60
Which Way?
P : Up
D : Down
1 : Don't Know
Default is 'Up' in 53
Response
--------
Down
.EXAMPLE
$a = Set-TimedPrompt -Prompt "Which Way?" -Options "Up", "Down", "D&on't Know" -SecondsToWait 60
Which Way?
U : Up
D : Down
O : Don't Know
Default is 'Up' in 58
PS C:\> $a.Tostring()
D&on't Know
#>
param (
[Parameter(Mandatory = $false)]
[Alias('Question')]
[string] $Prompt = "Please confirm you want to continue",
[Parameter(Mandatory = $false)]
[Alias('Timer', 'HowLong', 'Wait')]
[int] $SecondsToWait = 10,
[Parameter(Mandatory = $false)]
[Alias('Answers')]
[string[]] $Options = @("&Yes", "&No")
)
[int] $i = $SecondsToWait
[bool] $keepgoing = $true
[bool] $TimedOut = $false
[string] $Alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
[string] $Numa = "123456789"
[string] $AllowedKeys = ""
[string] $Color = 'Green'
$OptionsArray = @()
$Options | ForEach-Object {
if ($_.Contains('&')) {
[string] $initial = $_.Substring($_.IndexOf('&') + 1, 1 ).ToUpper()
} else {
[string] $initial = $_.ToString().Substring(0, 1).ToUpper().ToUpper()
}
if ($Alpha.Contains($initial)) {
$alpha = $alpha.Replace($initial, "")
} else {
$initial = $Numa.Substring(0, 1)
$Numa = $Numa.Substring(1)
}
$AllowedKeys += $initial
$OpHash = @{
Response = $_
NoAmp = $_.Replace('&', '')
ActionKey = $initial
}
$OpObject = New-Object -TypeName PSObject -Property $OpHash
$OpObject = $OpObject | Add-Member -MemberType ScriptMethod -Name ToString -Value { "{0}" -f $this.Response.PsBase.ToString() } -force -PassThru
$defaultProperties = @('Response')
$defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$defaultProperties)
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
$OpObject | Add-Member MemberSet PSStandardMembers $PSStandardMembers
$OptionsArray += $OpObject
}
$AllowedKeys = $AllowedKeys.ToUpper() + $AllowedKeys.ToLower()
Write-Host $Prompt -ForegroundColor Yellow
Write-Host ""
$OptionsArray | ForEach-Object { Write-Host " $($_.ActionKey) : $($_.NoAmp)" }
Write-Host ""
$CursorPosition = $Host.UI.RawUI.CursorPosition
while ($keepgoing) {
if ([console]::KeyAvailable) {
# Any key will quit
$x = [System.Console]::ReadKey($true)
switch ($AllowedKeys) {
{ $_.Contains($x.Key) } { $retval = $OptionsArray | Where-Object { $_.ActionKey -eq $x.Key }; $keepgoing = $false; $TimedOut = $false; break }
DEFAULT { $keepgoing = $true}
}
} else {
Switch ($i) {
{ $i -eq 0 } {$Color = 'Red'; break}
{ [math]::floor(($SecondsToWait / $i)) -gt [math]::floor($SecondsToWait * ( 1 / 3)) } { $Color = 'Red'; break }
{ [math]::floor(($SecondsToWait / $i)) -gt [math]::floor($SecondsToWait * (1 / 6)) } { $Color = 'Yellow'; break }
DEFAULT { $Color = 'Green'; break}
}
$Host.UI.RawUI.CursorPosition = $CursorPosition
Write-Host "Default is '$($OptionsArray[0].NoAmp)' in " -NoNewline
Write-Host $i.ToString().PadRight($SecondsToWait.ToString().Length) -NoNewline -ForegroundColor $Color
Write-Host ""
Start-Sleep -Milliseconds 1000
if ($i -eq 0) { $retval = $OptionsArray[0]; $keepgoing = $false; $TimedOut = $true}
$i -= 1
}
}
$retval
}