PowerShell – Prompt/Confirm User’s Choice (A Simple Yes/No function)

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
Advertisements

PowerShell Menu – Template .PS1 File

Hi.

Couldn’t find a batch menu demo that contained more than two layers in their example.
The template includes a main menu window, a sub-menu, and options to expand the console as deep as you want to go.

The menu and sub-menu loops until you select a valid entry from the displayed options and exit the script gracefully from the main menu.

<# # ==================================================================================================== # # Script:      PoSHMenuTemplate.ps1                                                                    #  # Version:     1.0.0                                                                                   #    # Author:      Calahan, Cory                                                                           # # Create date: 2013-07-17                                                                              # # Description: PowerShell "batch" menu template.                                                       # # Comments:    https://stealthfield.wordpress.com                                                       # # ==================================================================================================== # #>

Clear-Host
$Host.UI.RawUI.WindowTitle = "PoSH Menu Template"

function loadMainMenu()
{
    [bool]$loopMainMenu = $true
    while ($loopMainMenu)
    {
    Clear-Host  # Clear the screen.
    Write-Host -BackgroundColor Black -ForegroundColor White  “`n`tTeam Name – PowerShell Tasks – Version 1.0`t`n”
    Write-Host -BackgroundColor Black -ForegroundColor White  “`t`tMain Menu`t`t`n”
    $runasAlias = [Environment]::UserName
    Write-Host -BackgroundColor Black -ForegroundColor White "Running as: $runasAlias`n"
    Write-Host “`t`t`t1 - Select Sub-Menu 1”
    Write-Host “`t`t`t2 - Select Sub-Menu 2”
    Write-Host “`t`t`t3 - Select Sub-Menu 3”
    Write-Host “`t`t`t4 - Select Sub-Menu 4”
    Write-Host “`t`t`tQ --- Quit And Exit`n”
    Write-Host -BackgroundColor DarkCyan -ForegroundColor Yellow "`NOTICE:`t"
    Write-Host -BackgroundColor DarkCyan -ForegroundColor White  "`An extra warning.`t`n"
    $mainMenu = Read-Host “`t`tEnter Sub-Menu Option Number” # Get user's entry.
    switch ($mainMenu)
        {
        1{mainMenuOption1} # Calls function mainMenuOption1()
        2{} #To-do: Add.
        3{} #To-do: Add.
        4{} #To-do: Add.
        "q" {
                $loopMainMenu = $false
                Clear-Host
                Write-Host -BackgroundColor DarkCyan -ForegroundColor Yellow "`t`t`t`t`t"
                Write-Host -BackgroundColor DarkCyan -ForegroundColor Yellow "`tGoodbye!`t`t`t"
                Write-Host -BackgroundColor DarkCyan -ForegroundColor Yellow "`t`t`t`t`t"
                sleep -Seconds 1
                $Host.UI.RawUI.WindowTitle = "Windows PowerShell" # Set back to standard.
                Clear-Host
                Exit-PSSession
            }
        default {
            Write-Host -BackgroundColor Red -ForegroundColor White "You did not enter a valid sub-menu selection. Please enter a valid selection."
            sleep -Seconds 1
                }
        }
    }
return
}

function mainMenuOption1()
# This section is used for Loading Main Menu Option 1, .
{
    [bool]$loopSubMenu = $true
    while ($loopSubMenu)
    {
    $Host.UI.RawUI.WindowTitle = "PoSH Sub Menu 1"
    Clear-Host  # Clear the screen.
    Write-Host -BackgroundColor Black -ForegroundColor White  “`n`tTeam Name – PowerShell Tasks – Version 1.0`t`n”
    Write-Host -BackgroundColor Black -ForegroundColor White  “`t`tSub Menu 1`t`t`n”
    $runasAlias = [Environment]::UserName
    Write-Host -BackgroundColor Black -ForegroundColor White "Running as: $runasAlias`n"
    Write-Host “`t`t`t1 - Sub Menu 1 - Option 1”
    Write-Host “`t`t`t2 - Sub Menu 2 - Option 2”
    Write-Host “`t`t`t3 - Sub Menu 3 - Option 3”
    Write-Host “`t`t`tQ --- Quit And Return To Main Menu`n”
    $subMenu = Read-Host “`t`tEnter Sub-Menu 1 Option Number”
        switch ($subMenu)
        {
        1
            {
            loadSubMenu1Option1
            }
        2
            {
            #loadSubMenu2
            }
        3
            {
            #loadSubMenu3
            }
        q
            {
                $loopSubMenu = $false
            }
    default
            {
            Write-Host -BackgroundColor Red -ForegroundColor White "You did not enter a valid sub-menu selection. Please enter a valid selection."
            sleep -Seconds 1
            }
        }
    }
}

function loadSubMenu1Option1()
{
# Repeat Code Block from mainMenuOption1. Continue nesting based on features/selections you want.
}

# Start the Menu once loaded:
loadMainMenu

# Extras:
if ($clearHost) {Clear-Host}
if ($exitSession) {Exit-PSSession};