Powershell, combobox, get-aduser. Output users in color, depending on the condition

47 Views Asked by At

Please help me. How can I display a list of AD users in WinForm ComboBox in font color depending on the account status? For example: a disabled user is light gray, an unlimited password is blue.

enter image description here

$Users = Get-ADuser -filter * -Properties Name
Foreach ($User in $Users)
{
$ComboBox1.Items.Add($User.Name) ;
}
1

There are 1 best solutions below

0
Theo On

The only way to have different font colors in a ComboBox is by overriding the DrawItem event. For this you need to also set the ComboBox.DrawMode to OwnerDrawFixed.

Below code shows a demo form that uses that technique

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$Form               = New-Object system.Windows.Forms.Form
$Form.StartPosition = 'CenterScreen'
$Form.Text          = 'Colored Combobox'
$Form.Width         = 500
$Form.Height        = 200
$Form.TopMost       = $true

$ComboBox1               = New-Object System.Windows.Forms.ComboBox
$ComboBox1.Location      = New-Object System.Drawing.Point(10,10)
$ComboBox1.Width         = $Form.Width - ($ComboBox1.Margin.Horizontal * 4) -10
$ComboBox1.DropDownStyle = 'DropDownList'
# just for demo a nice large bold font
$combobox1.Font          = [System.Drawing.Font]::New("Calibri", 12, [System.Drawing.FontStyle]::Bold)
# override rendering of the Combobox.
$ComboBox1.DrawMode      = [System.Windows.Forms.DrawMode]::OwnerDrawFixed

# get an array of user object with the needed properties
$Users = Get-ADUser -Filter * -Properties PasswordNeverExpires, PasswordNotRequired | Sort-Object Name

# add the user names to the combobox
foreach ($user in $Users) { 
    [void]$ComboBox1.Items.Add($user.Name)
}
# set the text for the first item
$ComboBox1.SelectedIndex = 0
# create a variable that will keep the chosen item's index after the form is closed
$SelectedIndex = 0         

# add an event that draws each item.
$ComboBox1.Add_DrawItem({
    param(
        [object]$s,                                 # sender object
        [System.Windows.Forms.DrawItemEventArgs]$e  # event arguments
    )

    # clear the background for this item with the default color
    $e.DrawBackground()  
    if ($e.Index -ge 0) {
        # get the user object from the $Users array using the event index
        $user  = $script:Users[$e.Index]
        # determine the color to use when displaying this item in the combobox
        # use any of the KnownColor names (https://learn.microsoft.com/en-us/dotnet/api/system.drawing.knowncolor)
        $color = if (!$user.Enabled) { 'Gray' }
                 elseif ($user.PasswordNeverExpires -or $user.PasswordNotRequired) { 'Blue' }
                 else { 'Black' }
        $brush = [System.Drawing.SolidBrush]::New([System.Drawing.Color]::FromName($color))

        # paint the text
        $e.Graphics.DrawString($user.Name, $this.Font, $brush, $e.Bounds.X, $e.Bounds.Top)

        # save memory by disposing of the brush object
        $brush.Dispose()
    }
})

# add another event to capture the selected index to use after the form is closed
$ComboBox1.Add_SelectedIndexChanged({
    $script:SelectedIndex = $this.SelectedIndex
})
# add the combobox to the form
$Form.Controls.Add($ComboBox1)

[void]$Form.ShowDialog()
# remove from memory
$Form.Dispose()

Write-Host ('You selected user {0}' -f $Users[$SelectedIndex].Name)

enter image description here