Kae Travis

PowerShell Active Directory Group Picker

This post provides an example of a PowerShell Active Directory Group Picker.  You can also find a similar example of our PowerShell Active Directory People Picker.

When using one of my PowerShell GUI tools, we needed to select a valid Active Directory group.  I use the word ‘valid’ because merely prompting the user to enter free text created too much margin for error, so I needed to return a group that definitely existed.

There are ways to do this via PowerShell using the Remote Server Administration Tools (RSAT), but I don’t like my scripts relying on external tools and I like them to remain portable, whilst keeping the host machine clean.

Ultimately I ended up interfacing with Active Directory using PowerShell and ADSI.  The script basically invokes a function that launches a Windows Form.  It has a textbox to search for a group, and a ListBox to display them.  It then sets a variable in the script’s context with the selected group, which is accessible from the initial call.

cls
Add-Type -AssemblyName PresentationCore,PresentationFramework


function Select-ADObject
{  
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "Active Directory Search"
    $form.Size = New-Object System.Drawing.Size(340,320)
    $form.StartPosition = "CenterScreen"
        
    $SearchButton = New-Object System.Windows.Forms.Button
    $SearchButton.Location = New-Object System.Drawing.Point(260,10)
    $SearchButton.Size = New-Object System.Drawing.Size(50,23)
    $SearchButton.Cursor = [System.Windows.Forms.Cursors]::Hand
    $SearchButton.Text = 'Search'
    $SearchButton.Add_Click({

        $SearchButton.Enabled = $false
        $CancelButton.Enabled = $false

        #start progress bar
        $ProgressBar.Style="Marquee"
        $ProgressBar.MarqueeAnimationSpeed = 10;
      
        $searchVal = $SearchText.Text

        $job = Start-Job -ArgumentList $searchVal -ScriptBlock  {
            param($searchVal)                      
            if ($searchVal -ne $null -and $searchVal -ne "") {
                $objSearcher=[adsisearcher]"(&(objectCategory=group)(name=*$searchVal*))"
                $objSearcher.SizeLimit = 30

                $colProplist = "name"
                foreach ($i in $colPropList) { $objSearcher.PropertiesToLoad.Add($i) | out-null } 
	
                $colResults = $objSearcher.FindAll()
            }
            return $colResults
        }
    
        while($job.State -eq 'Running') {
            [System.Windows.Forms.Application]::DoEvents()
        }
        $results = $job | Receive-Job -AutoRemoveJob -Wait
              
        $ListBox.Items.Clear()                

        if ($results -eq $null -or $results.Count -eq 0) {
            $SearchButton.Enabled = $true
            $CancelButton.Enabled = $true
            #needed to reset marquee to 0
            $ProgressBar.Style="Blocks"
            $ProgressBar.MarqueeAnimationSpeed = 0;
            $ProgressBar.Value = 0;
            $SelectButton.Enabled = $false
            [System.Windows.MessageBox]::Show("Search returned no results.")
            return
        }

        
        foreach ($objResult in $results)
        {          
            [void] $ListBox.Items.Add(($objResult.Properties).name[0])	
        }

        $SearchButton.Enabled = $true
        $CancelButton.Enabled = $true
        #needed to reset marquee to 0
        $ProgressBar.Style="Blocks"
        $ProgressBar.MarqueeAnimationSpeed = 0;
        $ProgressBar.Value = 0;
        return
    })

    $form.Controls.Add($SearchButton)

    $SearchText = New-Object System.Windows.Forms.TextBox
    $SearchText.Location = New-Object System.Drawing.Point(10,11)
    $SearchText.Size = New-Object System.Drawing.Size(245,20)
    $SearchText.Multiline = $false   
    $SearchText.AcceptsReturn = $true 
    $SearchText.Add_KeyUp({
        if ($_.KeyCode -eq [System.Windows.Forms.Keys]::Enter) {
            $SearchButton.PerformClick()
        }
    })

    $form.Controls.Add($SearchText)

    $SelectButton = New-Object System.Windows.Forms.Button
    $SelectButton.Location = New-Object System.Drawing.Point(205,245)
    $SelectButton.Size = New-Object System.Drawing.Size(50,23)
    $SelectButton.Text = "Select"
    $SelectButton.Cursor = [System.Windows.Forms.Cursors]::Hand
    $SelectButton.Add_Click({ 
        if ($ListBox.SelectedItems.Count -eq 0) {
            [System.Windows.MessageBox]::Show("No item selected.")
            return
        }
        $script:selectedADGroup = $ListBox.SelectedItem; 
        write-host $ListBox.SelectedText; 
        $form.Close() 
    })
    $SelectButton.Enabled = $false
    $form.Controls.Add($SelectButton)

    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Point(260,245)
    $CancelButton.Size = New-Object System.Drawing.Size(50,23)
    $CancelButton.Text = "Cancel"
    $CancelButton.Cursor = [System.Windows.Forms.Cursors]::Hand
    $CancelButton.Add_Click({ $script:selectedADGroup = $null; $form.Close()})
    $form.Controls.Add($CancelButton)
      
    $ListBox = New-Object System.Windows.Forms.ListBox
    $ListBox.Location = New-Object System.Drawing.Point(10,40)
    $ListBox.Size = New-Object System.Drawing.Size(300, 20)
    $ListBox.Height = 200
    $ListBox.Add_SelectedIndexChanged({
        if ($ListBox.SelectedItems.Count -eq 1) {
            $SelectButton.Enabled = $true
        }
    })
    $form.Controls.Add($ListBox)

 
    $ProgressBar = New-Object System.Windows.Forms.ProgressBar
    $ProgressBar.Location = New-Object System.Drawing.Point(10, 246)
    $ProgressBar.Size = New-Object System.Drawing.Size(190, 21)
    $ProgressBar.Value = 0
    $ProgressBar.Style="Marquee"
    $ProgressBar.MarqueeAnimationSpeed = 0;
    $form.Controls.Add($ProgressBar)

    $form.TopMost = $true
    $form.Add_Shown({$form.Activate(); $SearchText.focus()})
    [void] $form.ShowDialog()

    return $script:selectedADGroup
}

$selectedObject = Select-ADObject

write-host $selectedObject
PowerShell Active Directory Group Picker
PowerShell Active Directory Group Picker

Leave a Reply