Pretty Out-GridView Dialog Boxes

by May 14, 2019

When you pipe objects to Out-GridView, the cmdlet shows the default properties, so when you use a grid view window as a selection dialog, you have limited control over what the user sees. This would dump the first 10 AD users into the grid view window, and the user can select one which is returned. However, the data shown in the grid view window looks awful:

Get-ADUser -ResultSetSize 10 -Filter * |
    Out-GridView -Title 'Select-User' -OutputMode Single |
    Select-Object -Property *

If you have no AD or have not installed the RSAT tools, here is a similar example using processes:.

Get-Process |
  Where-Object MainWindowTitle |
  Out-GridView -Title 'Which process do you want to kill?' -OutputMode Single |
  Stop-Process -WhatIf 

If you used Select-Object to limit the displayed properties, this would change the object type, so when you pipe the altered objects to subsequent cmdlets, they would not be able to work with the returned objects.

The solution is to leave the object type untouched, and instead change the default properties. This would be a solution for AD user objects, showing only Name and SID in the selection dialog:

[string[]]$visible = 'Name', 'SID'
$type = 'DefaultDisplayPropertySet'
[Management.Automation.PSMemberInfo[]]$i =
New-Object System.Management.Automation.PSPropertySet($type,$visible)

Get-ADUser -LDAPFilter '(samaccountname=schul*)' |
    Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $i -Force -PassThru |
    Out-GridView -Title 'Select-User' -OutputMode Single |
    Select-Object -Property *

And this would be the solution for the process selection dialog, showing process name, company, start time, and a window title:

[string[]]$visible = 'Name', 'Company','StartTime','MainWindowTitle'
$type = 'DefaultDisplayPropertySet'
[Management.Automation.PSMemberInfo[]]$i =
New-Object System.Management.Automation.PSPropertySet($type,$visible)



Get-Process |
  Where-Object MainWindowTitle |
  Sort-Object -Property Name |
  # important: object clone required
  Select-Object -Property * |
  Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $i -Force -PassThru |
  Out-GridView -Title 'Which process do you want to kill?' -OutputMode Single |
  Stop-Process -WhatIf

As it turns out, process objects will not accept a new DefaultDisplayPropertySet, so in this case a complete clone is required which you get by piping the objects through Select-Object 鈥揚roperty *. While this does change the object type, since all original properties are still kept, subsequent pipelined commands will continue to work because all pipeline binding can still occur.


psconf.eu 鈥� PowerShell Conference EU 2019 鈥� June 4-7, Hannover Germany 鈥� visit www.psconf.eu There aren鈥檛 too many trainings around for experienced PowerShell scripters where you really still learn something new. But there鈥檚 one place you don鈥檛 want to miss: PowerShell Conference EU – with 40 renown international speakers including PowerShell team members and MVPs, plus 350 professional and creative PowerShell scripters. Registration is open at www.psconf.eu, and the full 3-track 4-days agenda becomes available soon. Once a year it鈥檚 just a smart move to come together, update know-how, learn about security and mitigations, and bring home fresh ideas and authoritative guidance. We鈥檇 sure love to see and hear from you!

Twitter This Tip! ReTweet this Tip!