Use user input to stop a script

I need a way for a user to stop the current sub-script they're running and go back to the menu script that called the sub-script.

Here's an example:

There's a menu script that shows something like this:

1. Hire

2. Re-Hire

3. Termination

etc

Please choose a number:

If they choose 1, it goes to the hire script which prompts for name, office, title, etc like the following:

write-host "First Name: " -fore yellow -nonewline
$fname = read-host
write-host "Last Name: " -fore yellow -nonewline
$lname = read-host
write-host "Password: " -fore yellow -nonewline
$pass = read-host
write-host "Department: " -fore yellow -nonewline
$dept = read-host
write-host "Title: " -fore yellow -nonewline
$title = read-host
write-host "Manager (username): " -fore yellow -nonewline
$manager = read-host


So then let's say the user is in this script and doesn't want to do that right now and wants to get back to the main menu.  Instead of having to press Ctrl-C and close the script and re-open it, is there a way to catch a certain key press and then exit the sub-script back to the menu?

Could I put something like an if statement on each response that checks whether what the person entered was the ESC key or Ctrl-X or something along those lines?  Like:

write-host "First Name: " -fore yellow -nonewline
$fname = read-host
if ($fname -eq "Ctrl-X") {
.\menu.ps1
}

# I have tried different versions of this, and can't get it to work
...

Or could I wrap the whole thing in some type of while statement that says "while this key hasn't been pressed, do the following" but as soon as that key (ESC) or key combination (Ctrl-X) has been pressed, then go back to the menu?

Hope I'm making this clear...

July 14th, 2015 11:01am

Hi George,

this is somewhat feasible, buuut ......

why do you try to do a menu like that on the commandline?
Wouldn't it be easier to simply create a form that allows the user to enter all information in one go (and leave the fields blank, if he doesn't want them filled)?

PowerShell Studio from Sapien allows you to create a gui by simple drag&drop (and is the best PowerShell script editor around, definitely worth its money, especially if you frequently need to do menus and other GUI stuff).

Basically, you can group PowerShell consumers into two groups:

  • PowerShell Admins
  • Users

For PowerShell Admins you build functions, for Users you build GUIs.

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
July 14th, 2015 11:16am

Here is a good place to start to learn  how to build user interfaces with PowerShell: https://www.sapien.com/blog/topics/user-interface-design-for-administrators/
July 14th, 2015 11:22am

Sorry, I'm way too far into this build to scrap it and do it as a GUI.  Particularly if it requires purchasing a different product. 

Would like to know how to do it within PowerShell. 

This could be any kind of menu, not just user creation, etc.  Would like to know how to get back to the menu if I want to cancel the sub-script I'm in. 

Free Windows Admin Tool Kit Click here and download it now
July 14th, 2015 11:36am

This is what happens when we get in over our heads.

You cannot break out of a loop with any other method than a Ctl-C.  YOU can place a read in the loop and wait for a key then chose to exit.

July 14th, 2015 11:39am

Also have user type exit in box then test each answer for that value.

Free Windows Admin Tool Kit Click here and download it now
July 14th, 2015 11:40am

Well in that case, the only practical way to do this is to parse input and decide upon a dedicated exit-string.

Let's say you interpret "exit" as the escape string. You then compare each input with "exit" and that's it (Of course, then that escape string can never be used as actual input).

On the other hand, you can implement forms within a regular script (no need for PowerShell Studio either - it's a great tool in general, not just for building GUIs. I generally recommend using it, but it's not mandatory for Forms GUIs).

So yes, you can create a simple Form within your already existing script that allows the user to input the properties they want to enter, which upon return you will be able to interpret freely. Doing this manually will require you to read up on WinForms, which PSS would have saved you. I#d say it's worth the effort, not only for your current project, but also for future ones.

Cheers,
Fred

July 14th, 2015 11:44am

Or you could do this:

$body=@'
<label>First Name:<input id="firstName" type="input" ></label><br/>
<label>Last Name:<input type="input" ></label><br/>
<label>Password:<input type="input" ></label><br/>
<label>Department:<input type="input" ></label><br/>
<label>Title:<input type="input" ></label><br/>
<label>Manager (username):<input type="input" ></label><br/>
'@

$ie=New-Object -ComObject InternetExplorer.Application
$ie.Navigate('about:blank')
$ie.Document.body.innerHTML=$body
$ie.visible=$true
# enter data into displayed form then tretrive values by ID.
$ie.Document.getElementById('firstName').Value

You can make it as pretty as you want.

Free Windows Admin Tool Kit Click here and download it now
July 14th, 2015 12:01pm

Here is a sample form to show the basic format, that can be easily edited with the PowerShell ISE. It consists of button that shows a message dialog box. If you are familiar with forms from other languages, it is easy to do.

Function Button_Click()
{ 
   [System.Windows.Forms.MessageBox]::Show("Hello World." , "My Dialog Box")
}
Function Generate-Form {

    Add-Type -AssemblyName System.Windows.Forms    
    Add-Type -AssemblyName System.Drawing
    
    # Build Form
    $Form = New-Object System.Windows.Forms.Form
    $Form.Text = "My Form"
    $Form.Size = New-Object System.Drawing.Size(200,200)
    $Form.StartPosition = "CenterScreen"
    $Form.Topmost = $True

    # Add Button
    $Button = New-Object System.Windows.Forms.Button
    $Button.Location = New-Object System.Drawing.Size(35,35)
    $Button.Size = New-Object System.Drawing.Size(120,23)
    $Button.Text = "Show Dialog Box"
    $Form.Controls.Add($Button)

    #Add Button event 
    $Button.Add_Click({Button_Click})

    #Show the Form 
    $form.ShowDialog()| Out-Null 
 
} #End Function 
 
#Call the Function 
Generate-Form

Sample taken from the WIKI article

How to Add a PowerShell GUI Event Handler (Part 1)
http://social.technet.microsoft.com/wiki/contents/articles/25911.how-to-add-a-powershell-gui-event-handler-part-1.aspx

How to Add a PowerShell GUI Event Handler with Parameters (Part 2)
http://social.technet.microsoft.com/wiki/contents/articles/26207.how-to-add-a-powershell-gui-event-handler-with-parameters-part-2.aspx


July 14th, 2015 12:02pm

This is what happens when we get in over our heads.

You cannot break out of a loop with any other method than a Ctl-C.  YOU can place a read in the loop and wait for a key then chose to

Free Windows Admin Tool Kit Click here and download it now
July 14th, 2015 12:06pm

Or you can use a form which is actually very easy to build in notepad.

Add-Type -Assembly System.WIndows.Forms
$form=New-Object System.WIndows.Forms.Form
$form.StartPosition='CenterScreen'
$lbl=New-Object System.Windows.Forms.Label
$lbl.Text='First Name:'
$lbl.Location='5,10'
$lbl.Size='50,23'
$form.Controls.Add($lbl)
$tb=New-Object System.Windows.Forms.TextBox
$tb.Name='firstName'
$tb.Location='57,10'
$tb.size='120,20'
$form.Controls.Add($tb)
$btn=New-Object System.Windows.Forms.Button
$btn.Text='Ok'
$btn.DialogResult='Ok'
$btn.location='100,100'
$form.Controls.Add($btn)
$btn=New-Object System.Windows.Forms.Button
$btn.Text='Cancel'
$btn.DialogResult='Cancel'
$btn.location='170,100'
$form.Controls.Add($btn)
$form.CancelButton=$btn
if($form.ShowDialog() -eq 'Ok'){
   $form.Controls['firstname'].Text
}


And the escape key will abort the form without braking the script.

July 14th, 2015 12:32pm

This is what happens when we get in over our heads.

You cannot break out of a loop with any other method than a Ctl-C.  YOU can place a read in the loop and wait for a key then chose to

Free Windows Admin Tool Kit Click here and download it now
July 14th, 2015 12:33pm

You could use the empty string to be an indication of the desire to go back to the menu.
July 14th, 2015 1:23pm

Here is a sample form to show the basic format, that can be easily edited with the PowerShell ISE. It consists of button that shows a message dialog box. If you are familiar with forms from other languages, it is easy to do.

Function Button_Click()
{ 
   [System.Windows.Forms.MessageBox]::Show("Hello World." , "My Dialog Box")
}
Function Generate-Form {

    Add-Type -AssemblyName System.Windows.Forms    
    Add-Type -AssemblyName System.Drawing
    
    # Build Form
    $Form = New-Object System.Windows.Forms.Form
    $Form.Text = "My Form"
    $Form.Size = New-Object System.Drawing.Size(200,200)
    $Form.StartPosition = "CenterScreen"
    $Form.Topmost = $True

    # Add Button
    $Button = New-Object System.Windows.Forms.Button
    $Button.Location = New-Object System.Drawing.Size(35,35)
    $Button.Size = New-Object System.Drawing.Size(120,23)
    $Button.Text = "Show Dialog Box"
    $Form.Controls.Add($Button)

    #Add Button event 
    $Button.Add_Click({Button_Click})

    #Show the Form 
    $form.ShowDialog()| Out-Null 
 
} #End Function 
 
#Call the Function 
Generate-Form

Sample taken from the WIKI article

How to Add a PowerShell GUI Event Handler (Part 1)
http://social.technet.microsoft.com/wiki/contents/articles/25911.how-to-add-a-powershell-gui-event-handler-part-1.aspx

How to Add a PowerShell GUI Event Handler with Parameters (Part 2)
http://social.technet.microsoft.com/wiki/contents/articles/26207.how-to-add-a-powershell-gui-event-handler-with-parameters-part-2.aspx


Free Windows Admin Tool Kit Click here and download it now
July 14th, 2015 3:58pm

Here is a sample form to show the basic format, that can be easily edited with the PowerShell ISE. It consists of button that shows a message dialog box. If you are familiar with forms from other languages, it is easy to do.

Function Button_Click()
{ 
   [System.Windows.Forms.MessageBox]::Show("Hello World." , "My Dialog Box")
}
Function Generate-Form {

    Add-Type -AssemblyName System.Windows.Forms    
    Add-Type -AssemblyName System.Drawing
    
    # Build Form
    $Form = New-Object System.Windows.Forms.Form
    $Form.Text = "My Form"
    $Form.Size = New-Object System.Drawing.Size(200,200)
    $Form.StartPosition = "CenterScreen"
    $Form.Topmost = $True

    # Add Button
    $Button = New-Object System.Windows.Forms.Button
    $Button.Location = New-Object System.Drawing.Size(35,35)
    $Button.Size = New-Object System.Drawing.Size(120,23)
    $Button.Text = "Show Dialog Box"
    $Form.Controls.Add($Button)

    #Add Button event 
    $Button.Add_Click({Button_Click})

    #Show the Form 
    $form.ShowDialog()| Out-Null 
 
} #End Function 
 
#Call the Function 
Generate-Form

Sample taken from the WIKI article

How to Add a PowerShell GUI Event Handler (Part 1)
http://social.technet.microsoft.com/wiki/contents/articles/25911.how-to-add-a-powershell-gui-event-handler-part-1.aspx

How to Add a PowerShell GUI Event Handler with Parameters (Part 2)
http://social.technet.microsoft.com/wiki/contents/articles/26207.how-to-add-a-powershell-gui-event-handler-with-parameters-part-2.aspx


July 14th, 2015 3:58pm

Here is a sample form to show the basic format, that can be easily edited with the PowerShell ISE. It consists of button that shows a message dialog box. If you are familiar with forms from other languages, it is easy to do.

Function Button_Click()
{ 
   [System.Windows.Forms.MessageBox]::Show("Hello World." , "My Dialog Box")
}
Function Generate-Form {

    Add-Type -AssemblyName System.Windows.Forms    
    Add-Type -AssemblyName System.Drawing
    
    # Build Form
    $Form = New-Object System.Windows.Forms.Form
    $Form.Text = "My Form"
    $Form.Size = New-Object System.Drawing.Size(200,200)
    $Form.StartPosition = "CenterScreen"
    $Form.Topmost = $True

    # Add Button
    $Button = New-Object System.Windows.Forms.Button
    $Button.Location = New-Object System.Drawing.Size(35,35)
    $Button.Size = New-Object System.Drawing.Size(120,23)
    $Button.Text = "Show Dialog Box"
    $Form.Controls.Add($Button)

    #Add Button event 
    $Button.Add_Click({Button_Click})

    #Show the Form 
    $form.ShowDialog()| Out-Null 
 
} #End Function 
 
#Call the Function 
Generate-Form

Sample taken from the WIKI article

How to Add a PowerShell GUI Event Handler (Part 1)
http://social.technet.microsoft.com/wiki/contents/articles/25911.how-to-add-a-powershell-gui-event-handler-part-1.aspx

How to Add a PowerShell GUI Event Handler with Parameters (Part 2)
http://social.technet.microsoft.com/wiki/contents/articles/26207.how-to-add-a-powershell-gui-event-handler-with-parameters-part-2.aspx


Free Windows Admin Tool Kit Click here and download it now
July 14th, 2015 3:58pm

Here is a sample form to show the basic format, that can be easily edited with the PowerShell ISE. It consists of button that shows a message dialog box. If you are familiar with forms from other languages, it is easy to do.

Function Button_Click()
{ 
   [System.Windows.Forms.MessageBox]::Show("Hello World." , "My Dialog Box")
}
Function Generate-Form {

    Add-Type -AssemblyName System.Windows.Forms    
    Add-Type -AssemblyName System.Drawing
    
    # Build Form
    $Form = New-Object System.Windows.Forms.Form
    $Form.Text = "My Form"
    $Form.Size = New-Object System.Drawing.Size(200,200)
    $Form.StartPosition = "CenterScreen"
    $Form.Topmost = $True

    # Add Button
    $Button = New-Object System.Windows.Forms.Button
    $Button.Location = New-Object System.Drawing.Size(35,35)
    $Button.Size = New-Object System.Drawing.Size(120,23)
    $Button.Text = "Show Dialog Box"
    $Form.Controls.Add($Button)

    #Add Button event 
    $Button.Add_Click({Button_Click})

    #Show the Form 
    $form.ShowDialog()| Out-Null 
 
} #End Function 
 
#Call the Function 
Generate-Form

Sample taken from the WIKI article

How to Add a PowerShell GUI Event Handler (Part 1)
http://social.technet.microsoft.com/wiki/contents/articles/25911.how-to-add-a-powershell-gui-event-handler-part-1.aspx

How to Add a PowerShell GUI Event Handler with Parameters (Part 2)
http://social.technet.microsoft.com/wiki/contents/articles/26207.how-to-add-a-powershell-gui-event-handler-with-parameters-part-2.aspx


July 14th, 2015 3:58pm

The key combination can be ESC and then ENTER.

Consider you implement a function to read user's info from a keyboard, named readUserInput, and that you create an array with all menus you need to use, like this:

$menus=@(
    #... define all menus here (it's simple)
)

$answers=readUserInput $menus

if ($answers) {
    # user finished inputting; use the information contained in $answers
} else {
    # The user quit inputting
}

As you see, it's quite simple using the function readUserInput.

Here's a practical example:

$menus=@(
    @(
        '1 - Enter first, middle and last names'
        'First Name'
        'Middle Name'
        'Last Name'
    ),
    @(
        '2 - Enter department, title, section, password and dependency'
        'Department'
        'Title'
        'Section'
        'Password'
        'Dependency'
    ),
    @(
        '3 - Enter manager and assistant'
        'Manager'
        'Assistant'
    ),
    @(
        'x - quit (just ENTER is enough)'
    )
)

$answers=readUserInput $menus

if ($answers) {
    Write-Host -Separator "`n`t" -ForegroundColor Cyan `
        (,"`n`nThe option and the answers from user:"+$answers) 
    Write-Host Do something useful with them -ForegroundColor Magenta
} else {
    Write-Host The user quit inputting -ForegroundColor DarkMagenta
}

Each item of variable $menus contains the the specific item for the main menu, and all respective sub items ; nothing can be simpler.

A typical usage is self described in this image:


Only the function readUserInput is missing, so, here it is:

function readUserInput {
# - hardcoded values:
$mainMenuForeColor = 'Green'
$subMenuForeColor = 'Yellow'
$userWantsToRestartText = 'OK, let''s start again.'
$userWantsToRestartForeColor = 'DarkYellow'
$mainMenuTitle='Main menu options:'
$choiceQuestion='--- Your choice?'
$maxNumberOfItemsInSubmenu=10

    function readHost {
        foreach ($m in $menus[-1+$args[0]][1..$maxNumberOfItemsInSubmenu]) {
            Write-Host "`t$m`: " -ForegroundColor $subMenuForeColor -NoNewline
            if ($rh=Read-Host) {$rh} else {return $null}
    }}

    Write-Host -ForegroundColor $mainMenuForeColor -Separator "`n" -NoNewline `
        (,$mainMenuTitle+''+($menus=$args[0])+'').ForEach{
            $_ | select -first 1
        }

    while ($true) {
        switch (Read-Host "`n"$choiceQuestion) {
            {$_ -in 1..$($menus.Count)} {
                $answers = readHost $_
                if ($null -in $answers) {
                    Write-Host $userWantsToRestartText -ForegroundColor $userWantsToRestartForeColor
                } else {
                    return ,$_+$answers # full user's input
                }
            }
            default {return $null} # user quit inputting
}}}



Notice that the function above is 'parameterized' and contains hard coded values for easy customization; also, it requires PSv4 (maybe v3 is OK).

Free Windows Admin Tool Kit Click here and download it now
July 16th, 2015 11:28pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics