PowerShell Active Directory People Picker

This post contains a PowerShell Active Directory people picker, which is useful when we develop PowerShell forms that require searching for Active Directory users via their display name or username.

It’s a very similar concept to our PowerShell Active Directory Group Picker.  You can probably speed the search up by specifying an ADSI SearchRoot, this way it will only search a specific organisation unit in Active Directory as opposed to everywhere!  But for this example we’ll search everywhere.

We’ve also limited the results to 30 to speed up the search too.

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=person)(|(name=*$searchVal*)(samaccountname=*$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