This script builds upon my earlier Get-ColorInfo.ps1 script to provide a Winforms Powershell  ColorPicker dialog.  This diaalog returns a custom PSObject with two properties:

When you invoke this script, you may pass three optional parameters:

The [ColorPickerSortMode] is an enum of the available color sort modes:

Enum ColorPickerSortMode:

The image below shows a sample ColorPicker window:

 

 The ColorPicker shown here uses the 141 colors of the Windows Web Color Set.
 The ColorPicker is designed so that the color "Transparent" is anchored as the upper leftmost button of the color grid regardless of the selected sort order.
PowerShell
Edit|Remove
Import-Module -Name .\Exists.ps1 -force 
Import-Module -Name .\WinFormsLibrary.ps1 -Force 
 
Enum ColorPickerSortMode{ 
    ArgbHexValueAscending 
    ArgbHexValueDescending 
    BlueChannelAscending 
    BlueChannelDescending 
    BrightnessAscending 
    BrightnessDescending 
    GreenChannelAscending 
    GreenChannelDescending 
    HueAscending 
    HueDescending 
    NameAscending 
    NameDescending 
    RedChannelAscending 
    RedChannelDescending 
    SaturationAscending 
    SaturationDescending 
} 
 
#Get ColorInfoTable of Web Colors, Expands Powershell Color Object to Include Properties for Sort. 
$ArlColors = New-Object -TypeName System.Collections.ArrayList 
$ArlColors.AddRange($(.\Get-ColorInfo -ColorSet Web -OutputType ColorInfoTable)) 
$ArlColors.RemoveAt(0) #Remove Tranparent 
 
<# 
.NOTES 
Name:    Show-ColorPicker Function 
Author:  Randy Turner 
Version: 1.0c 
Date:    07/03/2019 
Revision History ----------------------------------------------------------------------- 
v1.0  - 06/20/2019 - Original release 
v1.0a - 06/21/2019 - Added additional comments for clarity & a minor bug fix 
v1.0b - 06/24/2019 - Added Tab support for color grid buttons 
v1.0c - 07/03/2019 - Added support for sort mode listbox as sorted list 
---------------------------------------------------------------------------------------- 
 
.SYNOPSIS 
Provides a wrapper for fumction used to Display a WinForms ColorPicker. 
 
.DESCRIPTION 
This script provides a WinForms ColorPicker Dialog that will display the 141 colors of the 
Windows Web Color Set. Two larger color swatches showing the Old and New color selections 
are included. There are 16 color sort options provided for Name, HSL values, & ARGB channels. 
upon selection a custom PSObject is returned with the DialogResult and the selected color. 
    ---------------------------------------------------------------------------------------- 
    Security Note: This is an unsigned script, Powershell security may require you run the 
    Unblock-File cmdlet with the Fully qualified filename before you can run this script, 
    assuming PowerShell security is set to RemoteSigned. 
    ----------------------------------------------------------------------------------------  
 
.PARAMETER SortMode Alias: S 
Optional, a custom [ColorPickerSortMode] object that sets the Color Sort Mode. 
 
.PARAMETER CurrentColor Alias: C 
Optional, a [System.Drawing.Color] that represents the current color to be changed 
 
.PARAMETER HideTransparent Alias: HT 
Optional, switch that will cause the color "Transparent" to be disabled & hidden. 
 
.EXAMPLE 
PS> $NC=Show-ColorPicker -SortMode BrightnessDescending -CurrentColor ([System.Drawing.Color]::Yellow) -HT 
} 
This example displays a ColorPicker with colors sorted by Name and Yellow loaded as the current color. 
#> 
function Show-ColorPicker{ 
    param ( 
        [Parameter(Mandatory = $False)][Alias('S')][ColorPickerSortMode]$SortMode = [ColorPickerSortMode]::BrightnessDescending, 
        [Parameter(Mandatory = $False)][Alias('C')][System.Drawing.Color]$CurrentColor = [System.Drawing.Color]::FromKnownColor([System.Drawing.KnownColor]::Control), 
        [Parameter(Mandatory = $False)][Alias('HT')][Switch]$HideTransparent) 
 
    Add-Type -A System.Windows.Forms 
 
    $NCV = $null #Initialize Return Value 
 
    #region Form Objects 
    #Add objects for Form 
    $ToolTipProvider = New-Object -TypeName Windows.Forms.ToolTip 
    $FormColorPicker = New-Object -TypeName Windows.Forms.Form 
    $PanelColorGrid = New-Object -TypeName Windows.Forms.Panel 
    $GrpSort = New-Object -TypeName Windows.Forms.GroupBox 
    $LbxSort = New-Object -TypeName Windows.Forms.ListBox 
    $ColorButtons = @(for ($C = 1; $C -le $ArlColors.Count+1; $C++) {New-Object -TypeName Windows.Forms.Button}) 
    $Labels = @(for ($C = 1; $C -le 4; $C++) {New-Object -TypeName Windows.Forms.Label}) 
    $Buttons = @(for ($C = 1; $C -le 2; $C++) {New-Object -TypeName Windows.Forms.Button}) 
    #endregion 
 
    #region Initialize ToolTipProvider 
    $ToolTipProvider.AutoPopDelay = 5000 
    $ToolTipProvider.InitialDelay = 100 
    $ToolTipProvider.ReshowDelay = 100 
    #endregion 
 
    #region Custom Event Code Blocks 
    <# 
    define a scriptblock to display the tooltip 
    add a _MouseHover event to display the corresponding tool tip 
    e.g. $txtPath.add_MouseHover($ShowHelp) 
    #> 
    $ShowColorToolTip={ 
    #display popup help 
    #each value is the name of a control on the panel. 
    $Tip = $this.BackColor.Name 
    $ToolTipProvider.SetToolTip($this,$Tip) 
    } 
 
    #Selection Button Click Events 
    $BtnOk_Click = { 
        $Script:NCV = Set-ReturnValue -ExitButton OK -NewColor $Labels[3].BackColor 
        $FormColorPicker.Close() 
    } 
    $BtnCancel_Click = { 
        $Script:NCV = Set-ReturnValue -ExitButton Cancel 
        $FormColorPicker.Close() 
    } 
    #ColorGrid Button Click 
    $ColorButton_Click = { 
        $Labels[3].BackColor = $This.Backcolor 
        $Labels[3].Text = [String]::Format("Name: {0},`r`n Hex Value: {1:X8}",$This.Backcolor.Name,$This.Backcolor.ToArgb()) 
        If($This.Backcolor.GetBrightness() -le 0.49)  
            {$Labels[3].ForeColor = [System.Drawing.Color]::White} 
        Else 
            {$Labels[3].ForeColor = [System.Drawing.Color]::Black} 
        #For Blue\Black Color Blind 
        If($This.Backcolor.Name -eq "Blue"){$Labels[3].ForeColor = [System.Drawing.Color]::White} 
    } 
    #SortIndex Changed 
    $SortIndexChanged = { 
        Sort-Colors -SortMode $LbxSort.SelectedIndex 
        Set-GridColors 
    } 
    #endregion 
     
    #region ColorPicker Form 
    $FormColorPicker.Name = "FormColorPicker" 
    $FormColorPicker.ClientSize = New-Object -TypeName Drawing.Size(422, 390) 
    $FormColorPicker.DataBindings.DefaultDataSourceUpdateMode = 0 
    $FormColorPicker.FormBorderStyle = [Windows.Forms.FormBorderStyle]::FixedSingle 
    $FormColorPicker.StartPosition = [Windows.Forms.FormStartPosition]::CenterParent 
    $FormColorPicker.Text = "Blueflame Dynamics - PSColorPicker"  
    $FormColorPicker.Icon = [BlueflameDynamics.IconTools]::ExtractIcon("imageres.dll", 186, 32) 
    $FormColorPicker.MaximizeBox = ` 
    $FormColorPicker.MinimizeBox = $False 
    #endregion 
 
    #region ColorPanel 
    $PanelColorGrid.Name = "PnlColorGrid" 
    $PanelColorGrid.Size = New-Object -TypeName Drawing.Size(143, 313) 
    $PanelColorGrid.Location = New-Object -TypeName Drawing.Point(13, 13) 
    $PanelColorGrid.Anchor = Get-Anchor ----R 
    $PanelColorGrid.BackColor = [System.Drawing.SystemColors]::Control 
    $PanelColorGrid.BorderStyle = [System.Windows.Forms.BorderStyle]::FixedSingle 
    $PanelColorGrid.DataBindings.DefaultDataSourceUpdateMode = 0 
    $PanelColorGrid.Cursor = Get-Cursor -Mode Default 
    $PanelColorGrid.Visible = $True 
    $PanelColorGrid.Enabled = $True 
    $PanelColorGrid.TabStop = $False 
    $FormColorPicker.Controls.Add($PanelColorGrid) 
    #endregion 
 
    #region Panel Buttons 
    $C = 1 #Column 
    $R = 1 #Row 
    $S = 1 #Sequence 
    $X = 3 #Horizontal Coordinate 
    $Y = 3 #Vertical Coordinate 
    For($Idx = 0; $Idx -lt $ColorButtons.Count; $Idx++){ 
        $ColorButtons[$Idx].Name = [String]::Format("BtnColorGrid{0:000}"$S) 
        $ColorButtons[$Idx].Parent = $PanelColorGrid 
        $ColorButtons[$Idx].Size = New-Object -TypeName Drawing.Size(15, 15) 
        $ColorButtons[$Idx].Location = New-Object -TypeName Drawing.Point($X$Y) 
        $ColorButtons[$Idx].FlatStyle = [Windows.Forms.FlatStyle]::Popup 
        $ColorButtons[$Idx].Visible = $True 
        $ColorButtons[$Idx].Enabled = $True 
        $ColorButtons[$Idx].TabStop = $True 
        $ColorButtons[$Idx].TabIndex = $Idx 
        #Anchor Tranparent on Button 1 of the grid 
        If($Idx -eq 0) 
            {$ColorButtons[$Idx].Backcolor = [System.Drawing.Color]::Transparent} 
        Else 
            {$ColorButtons[$Idx].Backcolor = [System.Drawing.Color]::FromName($ArlColors[$IdX-1].Name)} 
        $ColorButtons[$Idx].Add_MouseHover($ShowColorToolTip) 
        $ColorButtons[$Idx].Add_Click($ColorButton_Click) 
        #Layout buttons in an 8 button wide grid 
        If($S % 8 -eq 0){ 
            $R++ 
            $C = 1 
            $X = 3 
            $Y += 17} 
        Else{ 
            $C++ 
            $X += 17 
        } 
        $S++ 
    } 
    $ColorButtons[0].Enabled = $ColorButtons[0].Visible = !$HideTransparent.IsPresent 
    #endregion 
 
    #region Labels 
    $LblText = @("Current Color","Undefined","New Color","Undefined") 
    $LblPos  = @(0,0,0,0) 
    $LblSize = @(0,0,0,0) 
    $LblPos[0] = New-Object -TypeName Drawing.Point(175,13) 
    $LblPos[1] = New-Object -TypeName Drawing.Point(175,45) 
    $LblPos[2] = New-Object -TypeName Drawing.Point(175,105) 
    $LblPos[3] = New-Object -TypeName Drawing.Point(175,137) 
    $LblSize[0] = New-Object -TypeName Drawing.Size(100,23) 
    $LblSize[1] = New-Object -TypeName Drawing.Size(200,50) 
    $LblSize[2] = New-Object -TypeName Drawing.Size(100,23) 
    $LblSize[3] = New-Object -TypeName Drawing.Size(200,50) 
    For($Idx = 0; $Idx -lt $Labels.Count; $Idx++){ 
        $Labels[$Idx].Name = [String]::Format("Label{0}",$Idx+1) 
        $Labels[$Idx].Parent = $FormColorPicker 
        $Labels[$Idx].Visible = $True 
        $Labels[$Idx].Enabled = $True 
        $Labels[$Idx].Location = $LblPos[$Idx] 
        $Labels[$Idx].TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter 
        $Labels[$Idx].BorderStyle = [Windows.Forms.BorderStyle]::Fixed3D 
        $Labels[$Idx].Text = $LblText[$Idx] 
        $Labels[$Idx].Size = $LblSize[$Idx] 
    } 
    $Labels[1].Backcolor = $CurrentColor 
    $Labels[1].Text = [String]::Format("Name: {0},`r`n Hex Value: {1:X8}",$CurrentColor.Name,$CurrentColor.ToArgb()) 
    If($Labels[1].Backcolor.GetBrightness() -le 0.49)  
        {$Labels[1].ForeColor = [System.Drawing.Color]::White} 
    Else 
        {$Labels[1].ForeColor = [System.Drawing.Color]::Black} 
    #For Blue\Black Color Blind 
    If($Labels[1].Backcolor.Name -eq "Blue"){$Labels[1].ForeColor = [System.Drawing.Color]::White} 
    #endregion 
 
    #region GroupBox 
    $GrpSort.Name = "GrpSortBy" 
    $GrpSort.Parent = $FormColorPicker 
    $GrpSort.Visible = $True 
    $GrpSort.Enabled = $True 
    $GrpSort.Text = "Sort By:" 
    $GrpSort.Size = New-Object -TypeName Drawing.Size(235, 142)  
    $GrpSort.Location = New-Object -TypeName Drawing.Point(175,190) 
    #endregion 
 
    #region ListBox 
    $LbxSort.Name = "LbxSort" 
    $LbxSort.Parent = $GrpSort 
    $LbxSort.Visible = $True 
    $LbxSort.Enabled = $True 
    $LbxSort.Location = New-Object -TypeName Drawing.Point(5,15) 
    $LbxSort.Size = New-Object -TypeName Drawing.Size(225, 121) 
    $LbxSort.Sorted = $True 
 
    $Modes = @() 
    #Split Enum Names at Uppercase letters 
    [ColorPickerSortMode].GetEnumNames()|ForEach-Object{ 
        $Parts = [Regex]::Matches($_"[A-Z][a-z]+") 
        Switch($Parts.Count){ 
            2 {$Mode = [String]::Format("{0} - {1}"$Parts[0], $Parts[1])} 
            3 {$Mode = [String]::Format("{0} {1} - {2}"$Parts[0], $Parts[1], $Parts[2])} 
            4 {$Mode = [String]::Format("{0} {1} {2} - {3}"$Parts[0], $Parts[1], $Parts[2], $Parts[3])} 
            } 
        If($Mode.StartsWith("Argb")){$Mode=$Mode.Replace("Argb","ARGB")} 
        $Modes +$Mode 
        } 
    $LbxSort.SelectionMode = [System.Windows.Forms.SelectionMode]::One 
    $LbxSort.Items.AddRange($Modes) 
    $LbxSort.SelectedIndex = $SortMode 
    $LbxSort.Add_SelectedIndexChanged($SortIndexChanged) 
    #Perform Initial Sort, If needed. 
    If($SortMode -ne [ColorPickerSortMode]::NameAscending) 
        {Invoke-Command -ScriptBlock $SortIndexChanged}  
    #endregion 
 
    #region Selection Buttons 
    $BtnText = @('Ok','Cancel') 
    $BtnPos = @(0,0) 
    $BtnPos[0] = New-Object -TypeName Drawing.Point(260,340) 
    $BtnPos[1] = New-Object -TypeName Drawing.Point(335,340) 
    For($Idx = 0; $Idx -lt $Buttons.Count; $Idx++){ 
        $Buttons[$Idx].Name = [String]::Format("Btn{0}",$BtnText[$Idx]) 
        $Buttons[$Idx].Parent = $FormColorPicker 
        $Buttons[$Idx].Visible = $True 
        $Buttons[$Idx].Enabled = $True 
        $Buttons[$Idx].Text = $BtnText[$Idx] 
        $Buttons[$Idx].Location = $BtnPos[$Idx] 
        $Buttons[$Idx].Size = New-Object -TypeName Drawing.Size(75,30) 
    } 
    $Buttons[0].Add_Click($BtnOK_Click) 
    $Buttons[1].Add_Click($BtnCancel_Click) 
    #endregion 
 
    [Void]$FormColorPicker.ShowDialog() 
    $Script:NCV 
} 
 
Function Set-ReturnValue{ 
    param ( 
        [Parameter(Mandatory = $True)][Alias('EB')][System.Windows.Forms.DialogResult]$ExitButton, 
        [Parameter(Mandatory = $False)][Alias('NC')][System.Object]$NewColor = $null) 
    New-Object -TypeName PSObject -Property @{ExitButton = $ExitButton;Color = $NewColor} 
} 
 
Function Sort-Colors{ 
    param ([Parameter(Mandatory = $True)][Alias('S')][ColorPickerSortMode]$SortMode) 
    $SM = [ColorPickerSortMode] #Shortcut 
    $Sort = { 
    param( 
        [Parameter(Mandatory = $True)][Alias('P')][String]$Property, 
        [Parameter(Mandatory = $False)][Alias('S')][Switch]$Descending) 
 
    If($Descending.IsPresent) 
        {$Script:ArlColors = $Script:ArlColors|Sort-Object -Property $property -Descending}         
    Else 
        {$Script:ArlColors = $Script:ArlColors|Sort-Object -Property $property} 
    } 
    #& $Sort Name 
    Switch($SortMode){ 
    $SM::ArgbHexValueAscending  {& $Sort ARGB} 
    $SM::ArgbHexValueDescending {& $Sort ARGB -Descending} 
    $SM::BlueChannelAscending   {& $Sort B} 
    $SM::BlueChannelDescending  {& $Sort B -Descending} 
    $SM::BrightnessAscending    {& $Sort Brightness} 
    $SM::BrightnessDescending   {& $Sort Brightness -Descending} 
    $SM::GreenChannelAscending  {& $Sort G} 
    $SM::GreenChannelDescending {& $Sort G -Descending} 
    $SM::HueAscending           {& $Sort Hue} 
    $SM::HueDescending          {& $Sort Hue -Descending} 
    $SM::NameAscending          {& $Sort Name} 
    $SM::NameDescending         {& $Sort Name -Descending} 
    $SM::RedChannelAscending    {& $Sort R} 
    $SM::RedChannelDescending   {& $Sort R -Descending} 
    $SM::SaturationAscending    {& $Sort Saturation} 
    $SM::SaturationDescending   {& $Sort Saturation -Descending} 
    } 
} 
 
Function Set-GridColors{ 
    For($Idx = 0; $Idx -lt $ColorButtons.Count; $Idx++){ 
        #Anchor Tranparent on Button 1 of the grid 
        If($Idx -eq 0) 
            {$ColorButtons[$Idx].Backcolor = [System.Drawing.Color]::Transparent} 
        Else 
            {$ColorButtons[$Idx].Backcolor = [System.Drawing.Color]::FromName($Script:ArlColors[$Idx-1].Name)} 
    } 
}