none
create dynamic menu system with powershell

    Question

  • All-

    I am attempting to create a powershell script that will query a known object, and based on attributes of that object, creates a menu for the user of the script to interact with. for example:

    known object --> AD security group: "adgroup1"

    query group membership for adgroup1. for each member of adgroup1, create a menu option for the user to select (could be 1 member, could be 1000...who knows?). Allow the user of the script to select one of the menu items (which equates to a user object in AD) and execute something against that user object. I also need the ability within this menu system to always return back to a previous menu and exit the script. For possible solutions, dont focus on the AD example that I gave (it was the first thing that came to mind)...instead, focus more on the creation of the menu system; that is what I am struggling with.  Any help is appreciated!


    -K. Mortensen

    Monday, July 16, 2012 3:54 PM

Answers

  • Here is a simple idea that uses a hash table to keep track of numbers/values.  This script will dynamically present the user with a list of processes currently running, and based on the numeric selection, will provide more info on the chosen process:

    $processes = Get-Process
    $menu = @{}
    for ($i=1;$i -le $processes.count; $i++) {
        Write-Host "$i. $($processes[$i-1].name)"
        $menu.Add($i,($processes[$i-1].name))
        }
    
    [int]$ans = Read-Host 'Enter selection'
    $selection = $menu.Item($ans)
    Get-Process $selection


    Grant Ward, a.k.a. Bigteddy


    • Proposed as answer by jrv Thursday, July 19, 2012 2:00 PM
    • Edited by Bigteddy Thursday, July 19, 2012 2:02 PM Code fix
    • Marked as answer by K. Mortensen Friday, July 20, 2012 7:08 PM
    Thursday, July 19, 2012 1:34 PM

All replies

  • You wopuld not be able to easily do this at a prompt.  I suggest using WIndows FOrms and places teh list into a listbox or treeview.

    See this demo: http://www.designedsystemsonline.com/upload/Demo-Treeview.ps1.txt


    ¯\_(ツ)_/¯

    Monday, July 16, 2012 4:08 PM
  • Unfortunately, I need this to happen at a prompt. I know that it may not be easy...but I still need to get it done. I have used the following link as a starting place: http://technet.microsoft.com/en-us/library/ff730939.aspx This seems to work, I just need to find a way to dynamically generate menu items within this existing structure.  Further suggestions?


    -K. Mortensen

    Monday, July 16, 2012 6:16 PM
  • Hi,

    Can you be more specific with your question?

    Bill

    Monday, July 16, 2012 6:39 PM
    Moderator
  • Unfortunately, I need this to happen at a prompt. I know that it may not be easy...but I still need to get it done. I have used the following link as a starting place: http://technet.microsoft.com/en-us/library/ff730939.aspx This seems to work, I just need to find a way to dynamically generate menu items within this existing structure.  Further suggestions?


    -K. Mortensen

    I dio not see how what you have asked is possible as it has been asked.

    Consider a user presented with a menu of 1000 items.  How would they navigate the menu?

    The example you posted just uses the internal PowerShell prompting mechanism which is designed for a small number of items.


    ¯\_(ツ)_/¯

    Monday, July 16, 2012 6:59 PM
  • ok... valid point. forgive my exageration. let me revise: this menu system is not intended to have even close to 1000 entries. I would say that around 20 or less is more like what I will see. Now can we work toward a feasable solution?

    -K. Mortensen

    Wednesday, July 18, 2012 9:36 PM
  • sure... what additional information are you looking for? for the moment, i can give you the real life scenario that I am building this for if that will help: I am using powershell to hook into vmware vcenter servers. the user of the script would only know what vcenter (or esxi host) they need to connect to. once connected, the script should query the server to return a list of virtual datacenters that are hosted there as menu options. the end user would select a datacenter, at which point the script would query that datacenter and return all resource pools that are a part of that datacenter, and display them back as menu options. the end user would select a resource pool. at that point, the script would query to see if there were nested resource pools within that resource pool, repeating the procedure until the only objects in the final resource pool are virtual machines. when the user selects a resourc pool that only contains virtual machines, the script would either take or delete snapshots of all of the virtual machines. make sense?

    -K. Mortensen

    Wednesday, July 18, 2012 9:42 PM
  • Hi,

    What have you tried so far, and with what results? Are you getting any error messages? etc. etc. etc.

    Bill

    Wednesday, July 18, 2012 9:43 PM
    Moderator
  • sure... what additional information are you looking for? for the moment, i can give you the real life scenario that I am building this for if that will help: I am using powershell to hook into vmware vcenter servers. the user of the script would only know what vcenter (or esxi host) they need to connect to. once connected, the script should query the server to return a list of virtual datacenters that are hosted there as menu options. the end user would select a datacenter, at which point the script would query that datacenter and return all resource pools that are a part of that datacenter, and display them back as menu options. the end user would select a resource pool. at that point, the script would query to see if there were nested resource pools within that resource pool, repeating the procedure until the only objects in the final resource pool are virtual machines. when the user selects a resourc pool that only contains virtual machines, the script would either take or delete snapshots of all of the virtual machines. make sense?

    -K. Mortensen

    Earlier I recomended using a form. This is the most user friendly method.

    To post a simple menu the code you posted will work but becomes unreadable after about 5 items.

    I remeber this issue wit old DOS programs.  Why?

    Use a form.  It will do everything you ask and do it very simply.

    To do all of that with a text menu is like trying to got back to a Commodore 64 keyboard and prompt users with Basic menus to enter simple commands.  It si pointless.

    If this is your life's work then go ahead and do it.  We will attempt to answer any questions about the numerous problems you will encounter,

    Come to think of it this is like one of those Zen excercises in futility like -  "What is the sound of one hand clapping?"

    OR
    "Which came first...the chicken or the egg?"

    OR

    "Daddy.. why is the sky blue". (My favorite!)  (Answer: "Shut up and keep rowing!")

    Sorry but I know of no other way to illustrate my point

    You wish to use primitive and inappropriate methods to serve a user community in the 21st century.  Use a GUI. It is easier to navigate and much more flexible programmitically.

    .


    ¯\_(ツ)_/¯

    Thursday, July 19, 2012 12:57 AM
  • Let me clarify some things for you:

    - You do not know my user base; thus I will be the authoritative source on which is the "most user friendly method" for my scenario.
    - I have already given the requirement that I cannot use a form, thus for you to respond telling me to use a form is a waste of my time and yours.
    - You have spent a significant amount of time detailing why my methodology is archaic, "pointless", "primitive", and "inappropriate": do me a favor instead, and simply do not respond to any of my posts again. Leave me in my so called archaic, pointless, primitive, and inappropriate stupidity.

    If you find that the requirements that have been foisted on me to get a particular job done are too difficult for you to aid in an actual solution, and this forces you to reply instead with demeaning comments, then simply put.... I dont want or need to hear from you.

    I would rather fill this thread with information that will help myself, and others who might have similar unfortunate circumstances.


    -K. Mortensen

    Thursday, July 19, 2012 1:08 PM
  • I have started with the code posted here: http://technet.microsoft.com/en-us/library/ff730939.aspx

    I am just unsure of how to modify it so that the options presented are dynamically created and presented back to the end user.  no errors yet...just unsure of where to start. Thanks for your help!


    -K. Mortensen

    Thursday, July 19, 2012 1:15 PM
  • Here is a simple idea that uses a hash table to keep track of numbers/values.  This script will dynamically present the user with a list of processes currently running, and based on the numeric selection, will provide more info on the chosen process:

    $processes = Get-Process
    $menu = @{}
    for ($i=1;$i -le $processes.count; $i++) {
        Write-Host "$i. $($processes[$i-1].name)"
        $menu.Add($i,($processes[$i-1].name))
        }
    
    [int]$ans = Read-Host 'Enter selection'
    $selection = $menu.Item($ans)
    Get-Process $selection


    Grant Ward, a.k.a. Bigteddy


    • Proposed as answer by jrv Thursday, July 19, 2012 2:00 PM
    • Edited by Bigteddy Thursday, July 19, 2012 2:02 PM Code fix
    • Marked as answer by K. Mortensen Friday, July 20, 2012 7:08 PM
    Thursday, July 19, 2012 1:34 PM
  • With less than a handful of items BigTeddy has the only solution that might work.

    If you hadn't exagerated with a wil clainm of thousands I might hav esuggested teh same thig.

    In the end it is up to you to write the code.  YOU appear to be demanding that someon solve your problem and then you don't give us accurate information.


    ¯\_(ツ)_/¯

    Thursday, July 19, 2012 2:00 PM
  • Thank you! If I can ask for one last favor: would you mind providing a quick explanation of how this works, or adding some comments so that I can understand better? Again, thanks for your help!

    -K. Mortensen

    Friday, July 20, 2012 7:58 PM
  • We start by getting a list of processes.  We then loop through the list with a "for" loop, making use of the $i counter variable.  So we loop through the list, adding the number and the value to a hash table, and at the same time outputting the option to the screen.

    At the end of this, we have a number-driven menu on the screen, and the program has a hash table with number/value info stored together.

    When the user chooses an option, we look up that option in the hash table, and return the associated value.

    In this case the value is the name of a process, so we can use that to run another Get-Process specifically on that process that you selected.

    I hope this explanation is good enough.  If you're still unclear about it, let me know, and I'll try to explain better.


    Grant Ward, a.k.a. Bigteddy


    • Edited by Bigteddy Saturday, July 21, 2012 6:20 AM
    Saturday, July 21, 2012 6:20 AM
  • Here is a simple idea that uses a hash table to keep track of numbers/values.  This script will dynamically present the user with a list of processes currently running, and based on the numeric selection, will provide more info on the chosen process:

    $processes = Get-Process
    $menu = @{}
    for ($i=1;$i -le $processes.count; $i++) {
        Write-Host "$i. $($processes[$i-1].name)"
        $menu.Add($i,($processes[$i-1].name))
        }
    
    [int]$ans = Read-Host 'Enter selection'
    $selection = $menu.Item($ans)
    Get-Process $selection


    Grant Ward, a.k.a. Bigteddy


    This is a great start for what I need. I'm attempting to create a hash table or some type of script that will take data that is not in a table like the get-process has established. My goal here is specifically for use with Symantec app streaming. I want to take the data from "svscmd enum" which displays the installed virtual apps and place that into an option based script for deleting and or resetting a seleted installed virtual app.

    svscmd enum

    layer name: App Installed

    layer name: App Installed

    layer name: App Installed

    This is the output, but when using your above hash table I only get numbers nothing else.

    Wednesday, October 28, 2015 1:52 PM
  • Please do not piggy-back on a closed topic.  Start a question and add a link to this thread if it helps.

    Remember that this topic is 3 years old and the answer may not be valid for newer system.


    \_(ツ)_/

    Wednesday, October 28, 2015 2:01 PM
  • Here is a simple idea that uses a hash table to keep track of numbers/values.  This script will dynamically present the user with a list of processes currently running, and based on the numeric selection, will provide more info on the chosen process:

    $processes = Get-Process
    $menu = @{}
    for ($i=1;$i -le $processes.count; $i++) {
        Write-Host "$i. $($processes[$i-1].name)"
        $menu.Add($i,($processes[$i-1].name))
        }
    
    [int]$ans = Read-Host 'Enter selection'
    $selection = $menu.Item($ans)
    Get-Process $selection


    Grant Ward, a.k.a. Bigteddy


    Thanks that was what i was looking for!

    just added a do until statement that limits the input to the numbers populated by the list 

    #get child item of images folder and create a dynamic menu system from the contents

        $image = Get-ChildItem "D:\win 10\Image\*" | sort name

        $menu = @{}
        for ($i=1;$i -le $image.count; $i++) {
            Write-Host "$i. $($image[$i-1].name)"
            $menu.Add($i,($image[$i-1].name))
        #counts the number of items in list (this is used for the do until statement)
            $number = $menu.Count
            }

        do{
        $ans = Read-Host 'Enter selection' 
        }
        until ($ans -le $number)

    #convert selection string to integer and set selection variable
        [int]$intNum = [convert]::ToInt32($ans)

            $selection = $menu.Item($intNum)

    #selected item
    $selection 


    • Edited by m0del101 Friday, April 07, 2017 10:43 AM
    Friday, April 07, 2017 10:41 AM