Author Posts

December 9, 2014 at 3:13 am

Hi,

Im trying to search AD for a specific type of groups by name, and then list all groups. Then i want to give the user the ability to choose one of the presented groups by entering a number instead of typing the whole group name.

Question 1: How can i give every $Submenu (ad group) a number?

Question 2: When I choose for an example number 1, it will execute a command that adds the computer account to the specified group: ADD-ADGroupMember $Display_Selected_Item –members “$SAMname”

I would appreciate any advice!

Import-Module Activedirectory
Function Select-Adgroup{

Begin {

Write-Host “List all groups that starts with gpo_wsus from ActiveDirectory”

$Submenu=Get-ADGroup -Filter {name -like "gpo_wsus*"}|Select-Object name

}
Process {

write-host “`n Choose requested group: `n ”

$submenu | %{$_.name}

write-host “`n”

Read-Host “You may Select Something from the Submenu” -OutVariable Selected_Item

$Display_Selected_Item = $Submenu | ? {$_.name -eq “$($Selected_Item)”}

write-host “`n”
Write-Host “You Selected $Display_Selected_Item ”
write-host “`n”

}
}

December 9, 2014 at 5:00 am

If you don't mind having a bit of a GUI involved, this is very easy with Out-GridView and its -PassThru parameter. (Or -OutputMode Multiple , if you want the user to be able to make more than one selection). If I remember correctly, Out-GridView

$groups = Get-ADGroup -Filter {name -like "gpo_wsus*"} | Select-Object Name
$selectedGroup = $groups | Out-GridView -Title 'Select a group' -PassThru

Otherwise, you have two options that I can think of, off the top of my head. You can use the $host.UI.PromptForChoice() method (which will be a text-based menu on powershell.exe, and a GUI in the ISE; this is the same method that's used to present Confirm prompts, etc.), or you can write your own custom menu using Write-Host and Read-Host (which will be text-based in both environments.)

To use the PromptForChoice method, you have to construct a ChoiceDescription object for each item, and pass that array as the choices parameter to PromptForChoice(). You can find examples of that easily on the internet (such as http://technet.microsoft.com/en-us/library/ff730939.aspx ), so I won't spend too much more time on it here.

For Read-Host and Write-Host, I'd suggest using the array index (possibly offset by 1, if you don't want the choice numbers to start with zero) as the menu numbers. You'll have to validate the user's input yourself, and give them some way of choosing "cancel". Something along these lines:

function Get-Selection
{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string[]] $Choices,

        [ValidateNotNullOrEmpty()]
        [string] $Title = 'Menu'
    )

    $numberWidth = $groups.Count.ToString().Length

    Write-Host $Title
    Write-Host

    for ($i = 0; $i -lt $groups.Count; $i++)
    {
        Write-Host ("{0,$numberWidth}: {1}" -f ($i + 1), $groups[$i])
    }

    while ($true)
    {
        $input = Read-Host -Prompt 'Enter a selection number.  Leave blank to cancel.'

        if (-not $input)
        {
            # User cancelled.  Here we'll just return nothing, but you may want to
            # throw an exception instead, depending on how the calling code should
            # behave.

            return
        }

        $number = $input -as [int]

        if ($null -eq $number -or $number -lt 1 -or $number -gt $groups.Count)
        {
            Write-Host "$number is not a valid selection."
            continue
        }

        return $groups[$number - 1]
    }
}

$groups = @(Get-ADGroup -Filter {name -like "gpo_wsus*"} | Select-Object -ExpandProperty Name)
$selectedGroup = Get-Selection -Choices $groups -Title 'Select a group'