Advertisement
Lee_Dailey

Get-MenuChoice - 2017.04.11.03.40.29

May 22nd, 2017
732
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function Send-Beep
  2.     {
  3.     #region - Comment Based Help
  4.  
  5.     <#
  6.     .SYNOPSIS
  7.         Sends a beep via either "[console]::Beep()" or "[char]7' [aka - the ASCII BEL character].
  8.  
  9.     .DESCRIPTION
  10.         Sends a beep to the user using the BEL character if NOT in the ISE,
  11.             otherwise it uses the [console]::Beep() method.
  12.     .EXAMPLE
  13.         Send-Beep
  14.  
  15.         If in the ISE, uses [console]::Beep() with the default frequency of 1000 Hertz
  16.             for the default duration of 100 milliseconds.
  17.         If not in the ISE, sends a BEL character [aka - [char]7, ctrl-g] to the console.
  18.  
  19.     .EXAMPLE
  20.         Send-Beep -BeepFrequency 500 -BeepDuration 500
  21.  
  22.         If not in the ISE, sends a BEL character to the console.
  23.         If in the ISE, uses [console]::Beep() with Frequency = 500 Hertz & Duration = 500 milliseconds.
  24.  
  25.     .NOTES
  26.         Author = Lee Dailey
  27.         Contact = find me on Reddit
  28.         Version = 2017.04.11.03.40.43
  29.     #>
  30.  
  31.     #endregion
  32.  
  33.     #region - Parameters
  34.     [CmdletBinding()]
  35.     Param (
  36.         # Optional beep frequency in Hertz.
  37.         [Parameter(
  38.             Position = 0
  39.             )]
  40.             [ValidateRange(40, 4000)]
  41.             [int]
  42.             $BeepFrequency = 1000,
  43.  
  44.         # Optional beep duration in milliseconds.
  45.         [Parameter(
  46.             Position = 1
  47.             )]
  48.             [ValidateRange(10, 2000)]
  49.             [int]
  50.             $BeepDuration = 100
  51.         )
  52.     #endregion
  53.  
  54.     # The bell char doesn't work in the ISE
  55.     if ($Host.Name -match 'ISE')
  56.         {
  57.         [console]::Beep($BeepFrequency, $BeepDuration)
  58.         }
  59.         else
  60.         {
  61.         Write-Host ([char]7)
  62.         }
  63.     } # end >> function Send-Beep
  64.  
  65. function Get-MenuChoice
  66.     {
  67.     #region - Comment Based Help [CBH]
  68.  
  69.     <#
  70.     .SYNOPSIS
  71.         Displays a text menu & returns a valid response.
  72.  
  73.     .DESCRIPTION
  74.         Displays a string array as a menu & returns a valid response character by ...
  75.             - testing for 2 to 9 items in the array
  76.             - testing for a unique 1st character for each array item
  77.             - showing the array
  78.             - getting a response that matches one of the unique 1st characters
  79.             - returning that character as a string
  80.  
  81.     .EXAMPLE
  82.         Get-MenuChoice -MenuItems $TopMenu_Items
  83.  
  84.         - Displays the strings in the $TopMenu_Items array.
  85.         - Shows no menu title.
  86.         - Shows the default prompt.
  87.         - Returns [as a string] the first single-character input that matches the first character
  88.             of one of the menu items.
  89.  
  90.     .EXAMPLE
  91.         Get-MenuChoice -MenuItems ('1 - First thing', '2 - Second thing', 'x - Exit') -MenuTitle 'Top Menu' -MenuPrompt 'Pick one '
  92.  
  93.         - Displays the strings in the input array.
  94.         - Shows a title of "Top Menu".
  95.         - Shows a prompt of "Pick one ".
  96.         - Returns [as a string] the first single-character input that matches the first character
  97.             of one of the menu items.
  98.  
  99.     .NOTES
  100.         Author = Lee Dailey
  101.         Contact = find me on Reddit
  102.         Version = 2017.04.11.03.40.29
  103.            
  104.     #>
  105.  
  106.     #endregion
  107.  
  108.     #region - Parameters
  109.     # For some unknown reason, parameter help comments will not work without a CBH.
  110.     [CmdletBinding()]
  111.     [OutputType([String])]
  112.     Param (
  113.         # Required string array of menu items to display.
  114.         [Parameter(
  115.             Mandatory,
  116.             Position = 0
  117.             )]
  118.             [ValidateNotNullOrEmpty()]
  119.             [ValidateCount(2,9)]
  120.             [string[]]
  121.             $MenuItems,
  122.  
  123.         # Optional menu title.
  124.         [Parameter(
  125.             Position = 1
  126.             )]
  127.             [string]
  128.             $MenuTitle = '',
  129.  
  130.         # Optional user prompt.
  131.         [Parameter(
  132.             Position = 2
  133.             )]
  134.             [string]
  135.             $MenuPrompt = 'Please enter a choice from the above items '
  136.         )
  137.     #endregion
  138.  
  139.     #region - Init & test variables
  140.     $MenuChoice = ''
  141.     $ValidMenuChoices = $MenuItems | ForEach-Object {$_[0]}
  142.  
  143.     # check for dupe 1st chars in menu items list
  144.     if ($ValidMenuChoices.Count -ne ($ValidMenuChoices | Sort-Object | Get-Unique).Count)
  145.         {
  146.         Write-Error "The `$MenuItems variable has at least two items with identical first characters. >> $ValidMenuChoices <<" -ErrorAction Stop
  147.         }
  148.     #endregion
  149.  
  150.     while ($MenuChoice -notin $ValidMenuChoices)
  151.         {
  152.         Clear-Host
  153.         if (-not [string]::IsNullOrEmpty($MenuTitle))
  154.             {
  155.             $MenuTitle | Out-Host
  156.             }
  157.         $MenuItems | Out-Host
  158.         Write-host ''
  159.         $MenuChoice = (Read-Host $MenuPrompt).ToLower()
  160.         if ($MenuChoice -notin $ValidMenuChoices)
  161.             {
  162.             Send-Beep
  163.             }
  164.         }
  165.  
  166.     return $MenuChoice
  167.     } # end >> function Get-MenuChoice
  168.  
  169.  
  170. #region - Testing section - comment out or remove when finished
  171. #region - Menu data
  172.  
  173. # used to trigger duplicate 1st char of menu items error
  174. $BadTopMenu_Items = (
  175.     '1 - First submenu',
  176.     '2 - Second submenu',
  177.     '3 - Third submenu',
  178.     '2 - <<<< Dupe 1st char! <<<<<',
  179.     'x - Exit')
  180. $BadTopMenu_Title = 'Bad Top Menu Title'
  181. # the following line will trigger a stop error and show a Write-Error message
  182. #Get-MenuChoice -MenuItems $BadTopMenu_Items -MenuTitle $BadTopMenu_Title
  183.  
  184.  
  185. # these are for the multi-level menu test
  186. $TopMenu_Items = (
  187.     '1 - First submenu',
  188.     '2 - Second submenu',
  189.     '3 - Third submenu',
  190.     'x - Exit')
  191. $TopMenu_Title = 'Top Menu Title'
  192.  
  193. $SubMenu_1_Items = (
  194.     '1 - Do the 1st SM_1 thing',
  195.     '2 - Show a WScript Popup message',
  196.     'r - Return to Top Menu')
  197. $SubMenu_1_Title = 'Sub Menu One Title'
  198. $SubMenu_1_Prompt = 'Prompt for Sub Menu One'
  199.  
  200. $SubMenu_2_Items = (
  201.     'A - Perform action A',
  202.     'B - Do action B',
  203.     'C - Take action C',
  204.     'D - Display the 1st level contents of the current users temp folder.',
  205.     'r - Return to Top Menu')
  206. $SubMenu_2_Title = 'Sub Menu Two Title'
  207. $SubMenu_2_Prompt = 'Prompt for Sub Menu Two'
  208.  
  209. $SubMenu_3_Items = (
  210.     '1 - Item 3.1',
  211.     '2 - Item 3.2',
  212.     '3 - Start Notepad and load exit instructions.',
  213.     '4 - Item 3.4',
  214.     'r - Return to Top Menu')
  215. $SubMenu_3_Title = 'Sub Menu Three Title'
  216. $SubMenu_3_Prompt = 'Prompt for Sub Menu Three'
  217. #endregion
  218.  
  219.  
  220. $Choice = ''
  221. $CurrentMenu = 'TopMenu'
  222.  
  223. # ===== note >>>>> should i add an automatic `x - Exit` menu item to Get-MenuChoice?
  224. while ($Choice -ne 'x')
  225.     {
  226.     switch ($CurrentMenu)
  227.         {
  228.         'TopMenu'
  229.             {
  230.             $Choice = Get-MenuChoice -MenuItems $TopMenu_Items -MenuTitle $TopMenu_Title
  231.             switch ($Choice)
  232.                 {
  233.                 '1' {$CurrentMenu = 'SubMenu_1'; break}
  234.                 '2' {$CurrentMenu = 'SubMenu_2'; break}
  235.                 '3' {$CurrentMenu = 'SubMenu_3'; break}
  236.                 }
  237.             }
  238.         'SubMenu_1'
  239.             {
  240.             $ParamSplat = @{
  241.                 MenuItems = $SubMenu_1_Items
  242.                 MenuTitle = $SubMenu_1_Title
  243.                 MenuPrompt = $SubMenu_1_Prompt
  244.                 }
  245.             $Choice = Get-MenuChoice @ParamSplat
  246.             Write-Output ''
  247.             switch ($Choice)
  248.                 {
  249.                 '1' {Write-Output 'Doing the >> 1st << thing from Sub Menu ONE.'; pause; break}
  250.                 '2' {
  251.                     $PopupTimeout = 10
  252.                     $PopupMessage = "You chose item $Choice from $CurrentMenu." +
  253.                         "`n" +
  254.                         "`n" +
  255.                         "This dialog will auto-close in $PopupTimeout seconds."
  256.                     $PopupTitle = $SubMenu_1_Title
  257.                     (New-Object -ComObject "Wscript.Shell").Popup($PopupMessage, $PopupTimeout, $PopupTitle) |
  258.                         Out-Null
  259.                     break
  260.                     }
  261.                 'r' {$CurrentMenu = 'TopMenu'; break}
  262.                 }
  263.             }
  264.         'SubMenu_2'
  265.             {
  266.             $ParamSplat = @{
  267.                 MenuItems = $SubMenu_2_Items
  268.                 MenuTitle = $SubMenu_2_Title
  269.                 MenuPrompt = $SubMenu_2_Prompt
  270.                 }
  271.             $Choice = Get-MenuChoice @ParamSplat
  272.             Write-Output '';
  273.             switch ($Choice)
  274.                 {
  275.                 'a' {Write-Output 'Performing action >> A << from Sub Menu TWO.'; pause; break}
  276.                 'b' {Write-Output 'Doing action >> B << from Sub Menu TWO.'; pause; break}
  277.                 'c' {Write-Output 'Taking action >> C << from Sub Menu TWO.'; pause; break}
  278.                 'd' {
  279.                     Get-ChildItem $env:TEMP |
  280.                         Out-GridView
  281.                     }
  282.                 'r' {$CurrentMenu = 'TopMenu'; break}
  283.                 }
  284.             }
  285.         'SubMenu_3'
  286.             {
  287.             $ParamSplat = @{
  288.                 MenuItems = $SubMenu_3_Items
  289.                 MenuTitle = $SubMenu_3_Title
  290.                 MenuPrompt = $SubMenu_3_Prompt
  291.                 }
  292.             $Choice = Get-MenuChoice @ParamSplat
  293.             Write-Output '';
  294.             switch ($Choice)
  295.                 {
  296.                 '1' {Write-Output 'Item >> 3.1 << from Sub Menu THREE is what this is.'; pause; break}
  297.                 '2' {Write-Output 'This is item >> 3.2 << from Sub Menu THREE.'; pause; break}
  298.                 '3' {
  299.                     $NotepadMessage = "You selected item 3.$Choice from $CurrentMenu." +
  300.                         "`r`n" +
  301.                         "`r`n" +
  302.                         "Close Notepad to return to $CurrentMenu."
  303.                     $NotepadMessageFile = Join-Path -Path $env:TEMP -ChildPath 'NotepadMessage.txt'
  304.                     Set-Content -Value $NotepadMessage -Path $NotepadMessageFile
  305.                     Start-Process Notepad.exe -ArgumentList $NotepadMessageFile -Wait
  306.                     break
  307.                     }
  308.                 '4' {Write-Output 'The fourth item is >> 3.4 << from Sub Menu THREE.'; pause; break}
  309.                 'r' {$CurrentMenu = 'TopMenu'; break}
  310.                 }
  311.             }
  312.         } # end >> switch ($CurrentMenu)
  313.     } # end >> while ($Choice -ne 'x')
  314.  
  315. #endregion
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement