Here’s a sample of a custom function inspired from a previous PowerShell Tip of the Week:
function Confirm-UserChoice
{
[CmdletBinding()]
[Alias()]
[OutputType([bool])]
Param
(
[Parameter(Mandatory=$true,
Position=0)]
[Alias('Title')]
[string]
$PromptTitle,
[Parameter(Mandatory=$true,
Position=1)]
[Alias('Message')]
[string]
$PromptMessage,
[Parameter(Mandatory=$false,
Position=2)]
[Alias('YesDesc')]
[string]
$YesOptionDescription,
[Parameter(Mandatory=$false,
Position=3)]
[Alias('NoDesc')]
[string]
$NoOptionDescription
)
Begin
{
if ($PSBoundParameters['YesOptionDescription'])
{
$yes = New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Yes',$YesOptionDescription
}
else
{
$yes = New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Yes'
}
if ($PSBoundParameters['NoOptionDescription'])
{
$no = New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&No',$NoOptionDescription
}
else
{
$no = New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&No'
}
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no)
#$maybe = New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Maybe','Maybe we want to do provide more options'
#$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no,$maybe)
}
Process
{
$result = $Host.UI.PromptForChoice($PromptTitle, $PromptMessage, $options, 0) # Index of default option. '0' in this case represents 'Yes' in the above example, '1' for 'No'.
switch ($result)
{
0 {return $true}
1 {return $false}
}
}
End
{
Remove-Variable -Name yes,no,options,result
}
}
Where the usage looks like this:
Confirm-UserChoice -PromptTitle 'Confirm Action' -PromptMessage 'Do you really want to do this?' -YesOptionDescription 'Yes, I do.' -NoOptionDescription 'No, I do not.'
Bonus example: a slightly, possibly bad design decision, that let’s you make a mini pop-up selection at once:
function Confirm-OnTheFlyChoice
{
[CmdletBinding(DefaultParameterSetName='Default',
PositionalBinding=$false,
ConfirmImpact='Medium')]
[Alias('cotfc')]
Param
(
[Parameter(Mandatory=$true,
Position=0,
ParameterSetName='Default')]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[Alias('Title')]
[string]
$PromptTitle,
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
Position=1,
ParameterSetName='Default')]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[Alias('Message')]
[string]
$PromptMessage,
[Parameter(Mandatory=$true,
Position=2,
HelpMessage='Menu options:',
ParameterSetName='Default')]
[string[]]
$Option
)
Begin
{
$OptionArray = New-Object -TypeName System.Collections.ArrayList
Write-Verbose -Message 'Listing Parameters utilized:'
$PSBoundParameters.GetEnumerator() | ForEach-Object -Process { Write-Verbose -Message "$($PSItem)" }
} # END: Begin
Process
{
for ($i = 0; $i -lt $Option.Count; $i++)
{
$OptionArray.Add("&$($Option[$i])") | Out-Null
}
$options = [System.Management.Automation.Host.ChoiceDescription[]]($OptionArray)
$result = $Host.UI.PromptForChoice($PromptTitle, $PromptMessage, $options, 0)
} # END: Process
End
{
return $Option[$result]
Remove-Variable -Name OptionArray,options,result
} # END: End
}
Where the usage would be:
Confirm-OnTheFlyChoice -PromptTitle 'I needed a fast menu' -PromptMessage 'What do you select?' -Option Bird,Cat,Dog,Fish
Note on a bug: the Confirm-OnTheFlyChoice would introduce an issue as-is if you have two values with the same starting letter.
Example:
-Option Fish,Ferret
