############################################################################## ## ## Select-GraphicalFilteredObject.ps1 ## ## Adapted from Windows PowerShell Cookbook (O'Reilly) ## by Lee Holmes (http://www.leeholmes.com/guide) ## ## Display a Windows Form to help the user select a list of items piped in. ## Any selected items get passed along the pipeline. ## ## ie: ## ## PS >dir | Select-GraphicalFilteredObject -Title "Select items to delete" | Delete-Item -Whatif ## ############################################################################## param ( [string]$title = "Select the list of objects you wish to pass down the pipeline", [Switch]$checkOnClick # this is usually annoying ) $controlSpacing = 7 $objectArray = @($input) ## Ensure that they've piped information into the script if($objectArray.Count -eq 0) { Write-Error "This script requires pipeline input." return } function SelectAllCheckedListBoxItems( [Windows.Forms.CheckedListBox]$checkedListBox, [bool]$selected = $true ) { for ($i = 0; $i -lt $checkedListBox.Items.Count; $i++) { $checkedListBox.SetItemChecked( $i, $selected ) } } ## Load the Windows Forms assembly [void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") ## Create the main form $form = New-Object Windows.Forms.Form $form.Size = New-Object Drawing.Size @(600,600) $form.Padding = new Windows.Forms.Padding(4) ## Create the listbox to hold the items from the pipeline $listbox = New-Object Windows.Forms.CheckedListBox $listbox.CheckOnClick = $checkOnClick $listbox.Dock = "Fill" $form.Text = $title $listBox.Items.AddRange($objectArray) ## Create the button panel to hold the OK and Cancel buttons $buttonPanel = New-Object Windows.Forms.Panel $buttonPanel.Size = New-Object Drawing.Size @(600,30) $buttonPanel.Dock = "Bottom" ## Create the Cancel button, which will anchor to the bottom right $cancelButton = New-Object Windows.Forms.Button $cancelButton.Text = "Cancel" $cancelButton.DialogResult = "Cancel" $cancelButton.Top = $buttonPanel.Height - $cancelButton.Height - $controlSpacing $cancelButton.Left = $buttonPanel.Width - $cancelButton.Width - $controlSpacing - $controlSpacing $cancelButton.Anchor = "Right" ## Create the OK button, which will anchor to the left of Cancel $okButton = New-Object Windows.Forms.Button $okButton.Text = "Ok" $okButton.DialogResult = "Ok" $okButton.Top = $cancelButton.Top $okButton.Left = $cancelButton.Left - $okButton.Width - $controlSpacing $okButton.Anchor = "Right" ## Create the None button, which will anchor to the left of OK $noneButton = New-Object Windows.Forms.Button $noneButton.Text = "&None" $noneButton.Top = $cancelButton.Top $noneButton.Left = $okButton.Left - $noneButton.Width - $controlSpacing $noneButton.Anchor = "Right" $noneButton.add_Click( { SelectAllCheckedListBoxItems $listbox $false } ) ## Create the All button, which will anchor to the left of None $allButton = New-Object Windows.Forms.Button $allButton.Text = "&All" $allButton.Top = $cancelButton.Top $allButton.Left = $noneButton.Left - $allButton.Width - $controlSpacing $allButton.Anchor = "Right" $allButton.add_Click( { SelectAllCheckedListBoxItems $listbox $true } ) ## Add the buttons to the button panel $buttonPanel.Controls.Add($noneButton) $buttonPanel.Controls.Add($allButton) $buttonPanel.Controls.Add($okButton) $buttonPanel.Controls.Add($cancelButton) ## Add the button panel and list box to the form, and also set ## the actions for the buttons $form.Controls.Add($listBox) $form.Controls.Add($buttonPanel) $form.AcceptButton = $okButton $form.CancelButton = $cancelButton $form.Add_Shown( { $form.Activate() } ) ## Show the form, and wait for the response $result = $form.ShowDialog() ## If they pressed OK (or Enter,) go through all the ## checked items and send the corresponding object down the pipeline if($result -eq "OK") { foreach($index in $listBox.CheckedIndices) { $objectArray[$index] } }